home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / faq / wdj0597.zip / SDKANN.ZIP / SDKANN.TXT < prev    next >
Text File  |  1997-02-26  |  135KB  |  4,190 lines

  1. Please send us your annotations!  Just email them to
  2. 70302.2566@compuserve.com and indicate the topic and
  3. the help file that your annotation refers to. Help
  4. us build the SDK annotation database!
  5.  
  6. 1/9/97 NOTE:
  7. This version fixes a bug that caused some untoward
  8. crashes. This version also revises the logic for
  9. mstater.exe, and may actually work with Visual C++ 4.2,
  10. though I have not tried it yet.
  11.  
  12. 11/21/96 NOTE:
  13. The win32.hlp file that ships with Borland C++ v5.01 seems
  14. to be missing the help topics that correspond to annotations
  15. #126 (AVIFileOpen) and #140 (the STGM structure).
  16.  
  17. 8/29/96 NOTE:
  18.  
  19. Readers have reported that mstater.exe does not work
  20. with Visual C++ v4.2. Unfortunately, I don't yet have
  21. that version of the compiler. As soon as I get it, I will
  22. try to modify mstater.exe to work correctly with it.
  23.  
  24. 5/8/96 NOTE:
  25.  
  26. The AnnTater utility mentioned below has been mutated
  27. to work with the InfoViewer that is integrated in
  28. the Visual C++ IDE. Instead of running anntater.exe,
  29. run mstater.exe if you want to annotate the IDE
  30. InfoViewer (rather than any .hlp files you may have).
  31. Let me know if you have problems.
  32.  
  33.  
  34. 12/1/95 NOTE:
  35.  
  36. The WDJ annotation package now includes anntater.exe. 
  37. AnnTater contains all of our annotations and you can use it
  38. to automatically place our annotations in your help file. 
  39. Although I've tried to test this software in a variety of
  40. situations, USE IT AT YOUR OWN RISK.  If you have
  41. annotations of your own, you may want to back up your .ann
  42. file before running AnnTater. To use AnnTater, follow
  43. these steps. If you don't have annotations of your own, the
  44. easiest route is to delete your .ann file each time you run
  45. anntater.exe on a new installment of our annotations.
  46.  
  47. 1) invoke anntater.exe
  48. 2) select a type of help file (Windows 3.1 API or Win32 API)
  49. 3) if necessary, press the Locate button to specify the
  50.    path where this helpfile exists
  51. 4) select one or more annotations that you want to install
  52. 5) press the Copy button
  53. 6) press Done
  54.  
  55. Note that the program displays a checkmark beside
  56. each annotation that it believes it has successfully
  57. installed during the current session.
  58.  
  59.  
  60. ----------
  61.  
  62. This is the Windows Developer's Journal SDK Annotation File, a
  63. growing collection of useful annotations for the standard online Windows
  64. API help file, win31wh.hlp, which is included with every Windows C++
  65. compiler.  You can either cut and paste these annotations into your own
  66. SDK help file (use ALT-E-A to create a help topic annotation), or you
  67. can use anntater.exe to install them automatically for you.
  68.  
  69. If you have a useful annotation you would like to submit to our
  70. collection, send it to:
  71.  
  72.     70302.2566@compuserve.com
  73.  
  74. If we use your annotation, you will be listed as the
  75. contributor.  Our thanks to the dozens of readers whose
  76. contributions help us continue to build this database of
  77. useful information for the Windows programming community.
  78.  
  79.  
  80.  
  81.     Windows Developer's Journal
  82.  
  83.     "The Magazine for Windows Developers"
  84.  
  85. Windows Developer's Journal is the monthly publication for
  86. advanced Windows programmers.  We cover a variety of topics
  87. such as Windows 95 programming, NT programming device
  88. drivers, undocumented functions, compiler bugs, operating
  89. system bugs, graphics, MFC, multimedia, communications, and
  90. so on -- usually in the form of reusable code that you can
  91. use immediately (most of our code has been compiled with
  92. both Borland and Microsoft C/C++ compilers).  In addition,
  93. each month contains regular features like these:
  94.  
  95. * SDK Annotations
  96.     (they appear in the magazine before they appear in this file)
  97. * Bug++ of the Month
  98.     (nasty bugs in popular C++ compilers)
  99. * Tech Tips
  100.     (user-submitted tips and techniques)
  101. * Books in Brief
  102.     (quick looks at recent books)
  103. * Understanding NT
  104.     (covers NT-specific programming issues)
  105.  
  106. and more.  WDJ costs $34.99/year in the US, $45/year Canada/Mexico, or
  107. $64/year overseas.  To order a subscription, contact
  108.  
  109.     Miller Freeman
  110.     P.O. Box 56565
  111.     Boulder, CO 80322-6565
  112.     (800) 365-1425
  113.     (303) 678-0439
  114.     wdsub@rdpub.com
  115.  
  116. To subscribe by email or fax, include your name, address,
  117. phone number, MasterCard or Visa number, and expiration
  118. date.  From CompuServe, that email address would be
  119. something like this:
  120.  
  121.    >INTERNET:wdsub@rdpub.com
  122.  
  123.  
  124. Note: Annotation #35 proved to be incorrect and was
  125. removed.
  126.  
  127.  
  128. Note: due to a bug in WinHelp, it is not possible to display
  129. or annotate the GetRgnBox topic in the Visual C++ v1.5
  130. version of the helpfile. This prevents #67 from being
  131. properly installed.
  132.  
  133.   
  134. ------------------------------------------------------------
  135.  
  136. WDJ SDK Annotation #1
  137. TYPE:       Win3.1
  138. TOPIC:      Dialog Boxes
  139. KEYWORD:    Dialog Boxes
  140.  
  141. If a listbox is the first control in a dialog's tab order
  142. and the dialog box was not created with the WS_VISIBLE
  143. style, the listbox does not correctly draw itself with the
  144. focus.
  145.  
  146. Reference: p35, March 1993 Windows/DOS Developer's Journal.
  147.  
  148. ------------------------------------------------------------
  149.  
  150. WDJ SDK Annotation #2
  151. TYPE:       Win3.1
  152. TOPIC:      Property Lists
  153. KEYWORD:    Property Lists
  154.  
  155. The oft-quoted maxim that using window properties is slower
  156. than using class or window extra bytes (via
  157. GetWindowWord()/SetWindowWord()) is totally false if you use
  158. a global atom rather than a string to name the property. 
  159. Properties were about 20% slower than window words under
  160. Windows 3.0, but under Windows 3.1 GetProp() is about 300%
  161. faster than GetWindowWord().
  162.  
  163. Reference: p 49, March 1993 Windows/DOS Developer's Journal.
  164.  
  165. ------------------------------------------------------------
  166.  
  167. WDJ SDK Annotation #3
  168. TYPE:       Win3.1
  169. TOPIC:      WM_MOUSEMOVE (2.x)
  170. KEYWORD:    WM_MOUSEMOVE
  171.  
  172. The documentation incorrectly states that the x and y
  173. arguments are in screen coordinates.  They are in client
  174. coordinates. 
  175.  
  176.  
  177. ------------------------------------------------------------
  178.  
  179. WDJ SDK Annotation #4 (revised)
  180. TYPE:       Win3.1
  181. TOPIC:      SetWindowsHookEx (3.1)
  182. KEYWORD:    SetWindowsHookEx
  183.  
  184. SetWindowsHookEx() has a bug: using it to install a
  185. task-specific hook can cause various failures.  The
  186. workaround is to pass it a module handle rather than an
  187. instance handle.  You can obtain a module handle from
  188. GetModuleHandle().  If you only have the current instance
  189. handle and not the name of the module, use the following
  190. undocumented hack under Windows 3.1:
  191.  
  192. GetModuleHandle(MAKELP(0,hInstance));
  193.  
  194. If you #include <windowsx.h>, you can instead use the macro
  195. GetInstanceModule(hInstance).  Under Windows NT, just pass a
  196. NULL to obtain the handle of the current process.  Note that
  197. the MSDN News article on this subject has the arguments to
  198. MAKELP() backwards. 
  199.  
  200.  
  201. Reference: MSDN News #1, 1993
  202. Revised by: Tom Nolan
  203.  
  204. ------------------------------------------------------------
  205.  
  206. WDJ SDK Annotation #5
  207. TYPE:       Win3.1
  208. TOPIC:      CS_BYTEALIGNWINDOW 0x2000
  209. KEYWORD:    CS_BYTEALIGNWINDOW
  210.  
  211. The documentation makes it sound like this style bit is the
  212. one you want for efficient bitblts.  In fact, most of your
  213. bitblts will be to the client area of the window, not the
  214. non-client area, so CS_BYTEALIGNCLIENT is the style bit you
  215. should set if you are concerned about bitblt operation
  216. efficiency.  Unaligned windows are slower at VGA resolution,
  217. but typically not an issue with higher resolution
  218. adapters (such as 256-color SVGA). 
  219.  
  220. Reference: p65, December 1993 Windows/DOS Developer's Journal.
  221.  
  222.  
  223. ------------------------------------------------------------
  224.  
  225. WDJ SDK Annotation #6
  226. TYPE:       Win3.1
  227. TOPIC:      CODE Module Definition Statement
  228. KEYWORD:    CODE Module Definition Statement
  229.  
  230. The documentation for the FIXED attribute is incorrect. 
  231. Under Windows 3.1, if you mark code or data segments in your
  232. .exe FIXED, the loader ignores that attribute -- the
  233. segments will be moveable.  If you mark code or data
  234. segments in your .dll FIXED, however, the loader will make
  235. them fixed and will page lock them as well.  Due to the
  236. implementation of GlobalPageLock(), that can result in your
  237. segments using up precious DOS memory, eventually preventing
  238. Windows from spawning new applications (since each new
  239. application needs at least 512 bytes of DOS memory for a
  240. task database entry).  The October 1994 Windows
  241. Developer's Journal provides code to allocate fixed memory
  242. without using up precious conventional memory. 
  243.  
  244.  
  245. ------------------------------------------------------------
  246.  
  247. WDJ SDK Annotation #7
  248. TYPE:       Win3.1
  249. TOPIC:      WS_EX_TRANSPARENT 0x00000020L
  250. KEYWORD:    WS_EX_TRANSPARENT
  251.  
  252. Note that this bit does not really create transparent
  253. windows.  If you create a window with this style, it is true
  254. that the windows below it will show through as its
  255. background.  However, if you then move your new window, it
  256. will have the same background as it did in its original
  257. position -- blotting out whatever it is covering in its new
  258. position. 
  259.  
  260. ------------------------------------------------------------
  261.  
  262. WDJ SDK Annotation #8
  263. TYPE:       Win3.1
  264. TOPIC:      WM_NCHITTEST (2.x)
  265. KEYWORD:    WM_NCHITTEST
  266.  
  267. You can process this message to allow the user to drag a
  268. window that does not have a title bar.  When you receive a
  269. WM_NCHITTEST message and the mouse is in your client area
  270. (or whatever conditions you want to start the drag), just
  271. return HTCAPTION rather than passing the message on to
  272. DefWindowProc(). 
  273.  
  274. Reference: p 37, March 1993 Windows/DOS Developer's Journal.
  275.  
  276.  
  277. ------------------------------------------------------------
  278.  
  279. WDJ SDK Annotation #9
  280. TYPE:       Win3.1
  281. TOPIC:      WM_TIMER (2.x)
  282. KEYWORD:    WM_TIMER
  283.  
  284. Although it sounds odd, you can use a WM_TIMER message as a
  285. way to kill another application, if you can obtain the
  286. handle of the main of the application you want to kill. 
  287. Create a timer callback function that does nothing but pass
  288. its first argument (window handle) to DestroyWindow().  Then
  289. use PostMessage() to post (to the other app's main window) a
  290. WM_TIMER message that points to your callback function. 
  291. Your timer callback will get executed in the context of the
  292. target application. 
  293.  
  294. Reference: p 64, September 1992 Windows/DOS Developer's Journal.
  295.  
  296.  
  297.  
  298. ------------------------------------------------------------
  299.  
  300. WDJ SDK Annotation #10
  301. TYPE:       Win3.1
  302. TOPIC:      MemoryWrite (3.1)
  303. KEYWORD:    MemoryWrite
  304.  
  305. MemoryWrite() has a bug in it: it trashes the high 16 bits
  306. of the EDI register (the 32-bit version of the DI register). 
  307. The workaround is to save the register before calling
  308. MemoryWrite() and restore it afterward. 
  309.  
  310. Reference: p. 71, April 1994 Windows/DOS Developer's Journal
  311.  
  312.  
  313.  
  314. ------------------------------------------------------------
  315.  
  316. WDJ SDK Annotation #11
  317. TYPE:       Win3.1
  318. TOPIC:      EscapeCommFunction (2.x)
  319. KEYWORD:    EscapeCommFunction
  320.  
  321. The documentation omits one potential value for the
  322. nFunction parameter, although it is defined in windows.h. 
  323. The name is GETBASEIRQ and it returns the base address of
  324. the COM port in the lower word and the IRQ setting in the
  325. high word.  If the high word is -1 the port doesn't exist;
  326. if it is 0, the comm driver does not support this escape
  327. (which is the case, for example with some kinds of enhanced
  328. serial boards). 
  329.  
  330. Submitted by: Thomas Zeisluft
  331.  
  332. ------------------------------------------------------------
  333.  
  334. WDJ SDK Annotation #12
  335. TYPE:       Win3.1
  336. TOPIC:      MessageBox (2.x)
  337. KEYWORD:    MessageBox
  338.  
  339. Do not call MessageBox() from within the LibMain() of an
  340. implicitly-linked DLL.  It will fail because the application
  341. will not yet have a message queue at that point, and
  342. MessageBox() (or anything else) cannot create its window
  343. when the message queue does not yet exist.  Once the
  344. application executes its internal startup code and calls
  345. InitApp(), then it has a message queue and can safely call
  346. functions that create windows. 
  347.  
  348. ------------------------------------------------------------
  349.  
  350. WDJ SDK Annotation #13
  351. TYPE:       Win3.1
  352. TOPIC:      LB_ADDSTRING (2.x)
  353. KEYWORD:    LB_ADDSTRING
  354.  
  355. If you are changing the contents of a listbox (for example,
  356. by adding or deleting multiple strings), you may want to
  357. minimize screen redrawing and maximize speed by disabling
  358. window redrawing during your operation.  Follow these steps:
  359.  
  360.  1) Send a WM_SETREDRAW with wParam equal to FALSE to the listbox.
  361.  2) Perform your adds or deletes.
  362.  3) Send a WM_SETREDRAW with wParam equal to TRUE to the listbox.
  363.  4) Use InvalidateRect() to force the listbox to redraw itself.
  364.  
  365. Revised by V. Ramachandran
  366.  
  367. ------------------------------------------------------------
  368.  
  369. WDJ SDK Annotation #14
  370. TYPE:       Win3.1
  371. TOPIC:      RegisterWindowMessage (2.x)
  372. KEYWORD:    RegisterWindowMessage
  373.  
  374. Do you really need to register a private window message?
  375. Probably not, if all you need is an intra-app message number
  376. that does not conflict with any Windows message numbers. 
  377. Microsoft has revised its statement about what message
  378. numbers are available for your private use.  Microsoft now
  379. guarantees that you can use message numbers 0x8000 through
  380. 0xBFFF and they will not conflict with any system messages. 
  381. They also claim the next SDK (Chicago?) will define WM_APP
  382. equal to 0x8000 in windows.h. 
  383.  
  384. Reference: Microsoft Knowledge Base article Q86835
  385.  
  386.  
  387.  
  388. ------------------------------------------------------------
  389.  
  390. WDJ SDK Annotation #15
  391. TYPE:       Win3.1
  392. TOPIC:      WM_CHAR (2.x)
  393. KEYWORD:    WM_CHAR
  394.  
  395. The documentation incorrectly claims that wParam is the
  396. virtual key code.  In fact, it is the ASCII value of the key
  397. pressed.  For example, pressing the '$' (ASCII 0x5B) key
  398. produces a wParam equal to 0x5B -- if you interpreted that
  399. as a virtual key code, you would incorrectly believe that
  400. the user had pressed VK_HOME!
  401.  
  402. Submitted by: Brent Rector
  403.  
  404. ------------------------------------------------------------
  405.  
  406. WDJ SDK Annotation #16
  407. TYPE:       Win3.1
  408. TOPIC:      WinHelp (3.0)
  409. KEYWORD:    WinHelp
  410.  
  411. The documentation says that the return value is nonzero if
  412. WinHelp() is successful.  In fact, WinHelp() only returns
  413. failure for systemic problems, like being unable to allocate
  414. global memory, or being unable to spawn winhelp.exe.  If
  415. WinHelp() successfully passes your request to winhelp.exe,
  416. it returns success, period.  So, for example, if the named
  417. help file is invalid, or you try to jump to a help topic
  418. that does not exist, or any number of other logical errors,
  419. WinHelp() still returns success. 
  420.  
  421. ------------------------------------------------------------
  422.  
  423. WDJ SDK Annotation #17
  424. TYPE:       Win3.1
  425. TOPIC:      WM_ENTERIDLE (2.x)
  426. KEYWORD:    WM_ENTERIDLE
  427.  
  428. The documentation says that this messsage gets sent to your
  429. application's "main window".  In fact, a dialog sends the
  430. WM_ENTERIDLE message to its own parent window, which may or
  431. may not happen to be your application's main window. 
  432.  
  433.  
  434. ------------------------------------------------------------
  435.  
  436. WDJ SDK Annotation #18
  437. TYPE:       Win3.1
  438. TOPIC:      OPENFILENAME (3.1)
  439. KEYWORD:    OPENFILENAME
  440.  
  441. The documentation does not completely describe the behavior
  442. when selecting multiple files.  To allow the user to select
  443. multiple files, you turn on the flag OFN_ALLOWMULTISELECT. 
  444. If you do that and call GetOpenFileName(), and if the user then
  445. selects multiple files, then GetOpenFileName() will copy (into
  446. lpstrFile) the path, followed by a space, followed by
  447. space-separated filenames.  For example, if the user
  448. selected files "fred.1" and "fred.2" from directory
  449. "c:\test", lpstrFile would then point to the following
  450. string:
  451.  
  452.     "c:\test fred.1 fred.2"
  453.  
  454. However, the documentation does not point out that if the
  455. user selects only one file, then the path is not kept
  456. separate from the filename.  Using the previous example, if
  457. the user selected only file "fred.1", then lpstrFile would
  458. point to this:
  459.  
  460.     "c:\test\fred.1"
  461.  
  462. Submitted by Julian Templeman
  463.  
  464.  
  465.  
  466. ------------------------------------------------------------
  467.  
  468. WDJ SDK Annotation #19
  469. TYPE:       Win3.1
  470. TOPIC:      CreateRoundRectRgn (3.0)
  471. KEYWORD:    CreateRoundRectRgn
  472.  
  473. This function has a bug.  It will produce a GP fault if the
  474. region rectangle is empty (either nLeftRect equals
  475. nRightRect, or nBottomRect equals nTopRect).  About the only
  476. workaround is to create a wrapper function that first checks
  477. whether the rectangle is empty. 
  478.  
  479. Reference: p67, June 1994 Windows/DOS Developer's Journal^
  480. Submitted by Chris Mason
  481.  
  482.  
  483.  
  484. ------------------------------------------------------------
  485.  
  486. WDJ SDK Annotation #20
  487. TYPE:       Win3.1
  488. TOPIC:      EnableMenuItem (2.x)
  489. KEYWORD:    EnableMenuItem
  490.  
  491. When you are making changes to a window menu, the menu bar
  492. is not immediately updated.  To force those changes (such as
  493. enabling/disabling menu items) to be visible right away,
  494. make sure you call DrawMenuBar(). 
  495.  
  496. ------------------------------------------------------------
  497.  
  498. WDJ SDK Annotation #21
  499. TYPE:       Win3.1
  500. TOPIC:      DrawText (2.x)
  501. KEYWORD:    DrawText
  502.  
  503. DrawText() has an off-by-one error that can result in a GP
  504. fault.  The bug is evoked when you use pass an explicit
  505. string length instead of NULL-terminating the text string. 
  506. The bug is not evoked if you use the DT_NOPREFIX flag, or if
  507. you NULL-terminate the text string (the easiest workaround). 
  508.  
  509. Reference: p53, August 1994 Windows/DOS Developer's Journal
  510.  
  511. ------------------------------------------------------------
  512.  
  513. WDJ SDK Annotation #22
  514. TYPE:       Win3.1
  515. TOPIC:      WM_MEASUREITEM (3.0)
  516. KEYWORD:    WM_MEASUREITEM
  517.  
  518. Windows supports owner-draw menus, but only popup owner-draw
  519. menus work correctly.  If you try to create an owner-draw
  520. menubar for a window, Windows will not send you the
  521. WM_MEASUREITEM message as it should. 
  522.  
  523. Reference: Microsoft Knowledge Base article Q69969
  524.  
  525. ------------------------------------------------------------
  526.  
  527. WDJ SDK Annotation #23
  528. TYPE:       Win3.1
  529. TOPIC:      WINDOWPOS (3.1)
  530. KEYWORD:    WINDOWPOS
  531.  
  532. The documentation says that y is "the position of the right
  533. edge of the window".  It is, of course, the position of the
  534. top edge of the window. 
  535.  
  536.  
  537. ------------------------------------------------------------
  538.  
  539. WDJ SDK Annotation #24
  540. TYPE:       Win3.1
  541. TOPIC:      Shell Dynamic-Data Exchange Interface Overview (3.1)
  542. KEYWORD:    Shell Dynamic-Data Exchange Interface Overview
  543.  
  544. The documentation says you can use DDE to get a list of
  545. Program Manager groups by "issuing a request for the Group
  546. item." In fact, that is not the correct item name -- you
  547. must use 'Groups', not 'Group'. 
  548.  
  549.  
  550.  
  551. ------------------------------------------------------------
  552.  
  553. WDJ SDK Annotation #25
  554. TYPE:       Win3.1
  555. TOPIC:      TrackPopupMenu (3.0)
  556. KEYWORD:    TrackPopupMenu
  557.  
  558. The documentation incorrectly states that you can pass the
  559. TPM_RIGHTBUTTON flag if you want the menu to respond to the
  560. right (secondary) mouse button instead of the left (primary)
  561. mouse button.  In fact, passing TPM_RIGHTBUTTON causes the
  562. menu to respond to the right mouse button as well as the
  563. left.  There is apparently no combination of bits that cause
  564. the menu to respond only to the right mouse button. 
  565.  
  566.  
  567. ------------------------------------------------------------
  568.  
  569. WDJ SDK Annotation #26
  570. TYPE:       Win3.1
  571. TOPIC:      SetDlgItemText (2.x)
  572. KEYWORD:    SetDlgItemText
  573.  
  574. There is a bug in Windows that keeps SetWindowText() and
  575. SetDlgItemText() from working correctly when applied to an
  576. edit control owned by another application.  Rather than
  577. sending a WM_SETTEXT to the edit control as they should,
  578. these functions directly tinker with the target control's
  579. internal window structure to change its title.  The bug,
  580. then, is twofold:
  581.  
  582.  a) The target window is never notified that it
  583.     needs to repaint.
  584.  b) An edit control ignores its title, so changing
  585.     its title does not affect the text it contains.
  586.  
  587. The workaround is to use SendMessage() or PostMessage() to
  588. deliver a WM_SETTEXT to the target window.  If you use
  589. PostMessage(), make sure you pass a string pointer that is
  590. somehow guaranteed to still be valid whenever the target
  591. application gets around to fetching and processing the
  592. message. 
  593.  
  594. Reference: p. 71, September 1993 Windows/DOS Developer's Journal
  595.  
  596.  
  597. ------------------------------------------------------------
  598.  
  599. WDJ SDK Annotation #27
  600. TYPE:       Win3.1
  601. TOPIC:      GetMenuItemID (2.x)
  602. KEYWORD:    GetMenuItemID
  603.  
  604. The documentation says that this function returns 0 if the
  605. specified menu item is a separator.  In fact, although the
  606. resource compiler implicitly assigns separators an ID of 0,
  607. you can assign them any 16-bit ID you like (with
  608. ModifyMenu(), InsertMenu(), etc.) and this function will
  609. return the correct ID, not just zero. 
  610.  
  611.  
  612. ------------------------------------------------------------
  613.  
  614. WDJ SDK Annotation #28
  615. TYPE:       Win3.1
  616. TOPIC:      GetMetaFile (2.x)
  617. KEYWORD:    GetMetaFile
  618.  
  619. Most programs that write a "Windows metafile" to disk use a
  620. newer file format that this function does not understand. 
  621. Most programs read and write "placeable" metafiles, a
  622. metafile with a 22-byte header that contains a minimum
  623. bounding rectangle for the figure.  If you want to read in a
  624. metafile that may have been written by another application,
  625. you should open the file yourself and check the header to
  626. see if it is a placeable metafile.  See the SDK
  627. documentation for a description of "placeable Windows
  628. metafiles". 
  629.  
  630. Reference: p. 43, November 1994 Windows/DOS Developer's Journal
  631.  
  632.  
  633. ------------------------------------------------------------
  634.  
  635. WDJ SDK Annotation #29
  636. TYPE:       Win3.1
  637. TOPIC:      WritePrivateProfileString (3.0)
  638. KEYWORD:    WritePrivateProfileString
  639.  
  640. The documentation for WritePrivateProfileString() and the
  641. prototypes in windows.h, indicate that all strings passed in
  642. are LPCSTR (32-bit pointer to unmodifiable character
  643. string).  However, sometimes this function writes on your
  644. input string anyway! For one example, if you pass in the
  645. string
  646.  
  647. "Hello World     "
  648.  
  649. the function will remove the trailing spaces by writing a
  650. NULL byte after the 'd'.  If you were passing in a constant
  651. string that resided in a code segment, this aberrant
  652. behavior could result in a GP fault.  This function
  653. absolutely should not modify a string declared as LPCSTR,
  654. but since it does, beware!
  655.  
  656. Submitted by Charles Leamon
  657.  
  658. ------------------------------------------------------------
  659.  
  660. WDJ SDK Annotation #30
  661. TYPE:       Win3.1
  662. TOPIC:      GetMenuState (2.x)
  663. KEYWORD:    GetMenuState
  664.  
  665. In addition to the bits noted in the documentation, this
  666. function also correctly returns MF_POPUP for a submenu. 
  667. Oddly, if you located the popup by position, the
  668. MF_BYPOSITION flag will also be set in the returned flags,
  669. although it is not on when used to locate normal menu items. 
  670. Note that some of these flags equate to zero, so you cannot
  671. just AND them with the returned flags to see if they are on. 
  672. Here are the flags that equate to zero, along with the
  673. expression you can use to infer their presence:
  674.  
  675.  Zero Flag               Expression to test for flag
  676.  ==============   =================================
  677.  MF_ENABLED       !(Flag&~(MF_DISABLED|MF_GRAYED)) 
  678.  MF_UNCHECKED     !(Flag&~MF_CHECKED)              
  679.  MF_STRING        !(Flag&~(MF_BITMAP|MF_OWNERDRAW))
  680.  
  681.  
  682. ------------------------------------------------------------
  683.  
  684. WDJ SDK Annotation #31
  685. TYPE:       Win3.1
  686. TOPIC:      GetWindowPlacement (3.1)
  687. KEYWORD:    GetWindowPlacement
  688.  
  689. From the documentation, you might think the following code
  690. would work:
  691.  
  692.  WINDOWPLACEMENT Info;
  693.  GetWindowPlacement(hWnd, &Info);
  694.  
  695. In fact, it won't.  You must remember to initialize the
  696. "length" field of the structure before calling this
  697. function.  The following code works:
  698.  
  699.  WINDOWPLACEMENT Info;
  700.  Info.length  = sizeof(Info);
  701.  GetWindowPlacement(hWnd, &Info);
  702.  
  703. Submitted by Pete Davis
  704.  
  705.  
  706.  
  707. ------------------------------------------------------------
  708.  
  709. WDJ SDK Annotation #32
  710. TYPE:       Win3.1
  711. TOPIC:      CreateCompatibleBitmap (2.x)
  712. KEYWORD:    CreateCompatibleBitmap
  713.  
  714. The description of height and width parameters states that
  715. these values are in bits, when actually they are in pixels. 
  716.  
  717. Submitted by Charles Leamon
  718.  
  719.  
  720. ------------------------------------------------------------
  721.  
  722. WDJ SDK Annotation #33
  723. TYPE:       Win3.1
  724. TOPIC:      LoadCursor (2.x)
  725. KEYWORD:    LoadCursor
  726.  
  727. The documentation says that you should call DestroyCursor()
  728. for cursors loaded via LoadCursor().  That is wrong -- you
  729. should only call DestroyCursor() for cursors created with
  730. CreateCursor(). 
  731.  
  732. Submitted by Charles Leamon^
  733. Reference: Microsoft Knowledge Base article Q84779
  734.  
  735.  
  736. ------------------------------------------------------------
  737.  
  738. WDJ SDK Annotation #34
  739. TYPE:       Win3.1
  740. TOPIC:      lstrcpyn (3.1)
  741. KEYWORD:    lstrcpyn
  742.  
  743. The documentation for lstrcpyn() states that the last
  744. parameter (cChars) is the number of characters to be copied,
  745. when in fact the number of characters will be cChars-1. 
  746. That's convenient, but it's not what it says and it's
  747. inconsistent with the standard ANSI C run-time function
  748. strncpy(), which does copy the specified count.  In other
  749. words, unlike strncpy(), this function always
  750. NULL-terminates the destination string. 
  751.  
  752. Submitted by Charles Leamon
  753.  
  754.  
  755. ------------------------------------------------------------
  756.  
  757.  
  758. WDJ SDK Annotation #36
  759. TYPE:       Win3.1
  760. TOPIC:      ExitWindows (3.0)
  761. KEYWORD:    ExitWindows
  762.  
  763. The documentation is incomplete.  To just terminate Windows
  764. and return control to DOS, pass a zero in the dwReturnCode
  765. parameter. 
  766.  
  767. Submitted by Charles Leamon^
  768. Reference: Microsoft Knowledge Base article Q100359
  769.  
  770.  
  771. ------------------------------------------------------------
  772.  
  773. WDJ SDK Annotation #37
  774. TYPE:       Win3.1
  775. TOPIC:      OpenFile (2.x)
  776. KEYWORD:    OpenFile
  777.  
  778.  
  779. The descriptions for OF_CANCEL and OF_PROMPT are incorrect. 
  780. OF_CANCEL does not add a cancel button to the 'File not
  781. found' (OF_PROMPT) dialog.  Even if it did, how would the
  782. caller know the user pressed the cancel button (only one
  783. error return is defined for OpenFile())? The OF_PROMPT
  784. dialog does not prompt the user to insert a diskette into
  785. drive A:
  786.  
  787. Submitted by Charles Leamon
  788.  
  789.  
  790.  
  791. ------------------------------------------------------------
  792.  
  793. WDJ SDK Annotation #38
  794. TYPE:       Win3.1
  795. TOPIC:      WM_NCHITTEST (2.x)
  796. KEYWORD:    WM_NCHITTEST
  797.  
  798. The documentation claims that this message is sent to the
  799. window that used SetCapture() to capture mouse input.  That
  800. is totally false.  The window whose handle is passed to
  801. SetCapture() will never receive any WM_NCHITTEST messages
  802. (no matter where you move the moust) while the mouse is
  803. captured. 
  804.  
  805. Submitted by V. Ramachandran
  806.  
  807.  
  808. ------------------------------------------------------------
  809.  
  810. WDJ SDK Annotation #39
  811. TYPE:       Win3.1
  812. TOPIC:      TabbedTextOut (3.0)
  813. KEYWORD:    TabbedTextOut
  814.  
  815. The documentation claims that the tab stops are in device
  816. units (pixels), but that is not true.  The tab stops are
  817. treated as logical units, not device units. 
  818.  
  819. Submitted by Dan Miser^
  820. Reference: Microsoft Knowledge Base article Q113253
  821.  
  822.  
  823. ------------------------------------------------------------
  824.  
  825. WDJ SDK Annotation #40
  826. TYPE:       Win3.1
  827. TOPIC:      LoadIcon (2.x)
  828. KEYWORD:    LoadIcon
  829.  
  830. The documentation says that you should call DestroyIcon()
  831. for cursors loaded via LoadIcon().  That is wrong -- you
  832. should only call DestroyIcon() for icons created with
  833. CreateIcon(). 
  834.  
  835. Submitted by Charles Leamon^
  836. Reference: Microsoft Knowledge Base article Q84779
  837.  
  838.  
  839. ------------------------------------------------------------
  840.  
  841. WDJ SDK Annotation #41
  842. TYPE:       Win3.1
  843. TOPIC:      COMPAREITEMSTRUCT (3.0)
  844. KEYWORD:    COMPAREITEMSTRUCT
  845.  
  846. Note that Windows has to send a WM_COMPAREITEM message when
  847. a new item is added to the list, in order to determine its
  848. correct position.  That means it does not know the position
  849. of the new item yet, so (contrary to the documentation) the
  850. itemID2 field in this structure will be -1 -- do not assume
  851. it will be a legal index value. 
  852.  
  853. Submitted by V. Ramachandran
  854.  
  855.  
  856. ------------------------------------------------------------
  857.  
  858. WDJ SDK Annotation #42
  859. TYPE:       Win3.1
  860. TOPIC:      GetProcAddress (2.x)
  861. KEYWORD:    GetProcAddress
  862.  
  863. In attempting to locate the named function in the target
  864. module, GetProcAddress() converts the function name to
  865. uppercase and then performs a case-sensitive search.  That
  866. means that GetProcAddress() cannot locate functions exported
  867. with names containing lowercase characters.  Normally,
  868. that's not a problem, as the __pascal calling sequence
  869. forces uppercase names.  However, depending on the compiler
  870. and linker tools and options you use, it is possible to
  871. export __cdecl calling sequence functions with lowercase
  872. characters, resulting in a function that GetProcAddress()
  873. cannot locate. 
  874.  
  875. Submitted by Keith Bluestone
  876.  
  877. ------------------------------------------------------------
  878.  
  879. WDJ SDK Annotation #43
  880. TYPE:       Win3.1
  881. TOPIC:      SetScrollRange (2.x)
  882. KEYWORD:    SetScrollRange
  883.  
  884. The documentation says you can use this function to hide or
  885. show standard scroll bars, but does not tell you how!
  886. Basically, if you specify the same value for both the
  887. minimum (nMin) and maximum (nMax) scrolling positions, the
  888. function will hide the scroll bar.  If the two positions are
  889. not equal, the function will display the scroll bar. 
  890.  
  891. Submitted by Paul Bonneau
  892.  
  893.  
  894. ------------------------------------------------------------
  895.  
  896. WDJ SDK Annotation #44
  897. TYPE:       Win3.1
  898. TOPIC:      LoadLibrary (2.x)
  899. KEYWORD:    LoadLibrary
  900.  
  901. If LoadLibrary() cannot find the library, it may display an
  902. error message to the user, depending upon the state of
  903. Windows' "error mode".  If you want to handle that case
  904. yourself and make sure Windows does not display the error
  905. message, see the documentation for the function
  906. SetErrorMode().  For example, the following code attempts to
  907. load the library ctl3d.dll, but does not emit an error
  908. message if it is not found. 
  909.  
  910. HINSTANCE Ctl3d;^
  911. UINT OldFlag = SetErrorMode(SEM_NOOPENFILEERRORBOX);^
  912. Ctl3d        = LoadLibrary("ctl3d.dll");^
  913. SetErrorMode(OldFlag);  // restore previous mode^
  914. if(Ctl3d <= HINSTANCE_ERROR)^
  915.     // LoadLibrary() failed for some reason^
  916.  
  917.  
  918. ------------------------------------------------------------
  919.  
  920. WDJ SDK Annotation #45
  921. TYPE:       Win3.1
  922. TOPIC:      LoadLibrary (2.x)
  923. KEYWORD:    LoadLibrary
  924.  
  925.  
  926. The documentation claims this function returns an error code
  927. of 0 if "System was out of memory, executable file was
  928. corrupt, or relocations were invalid".  However, if a
  929. library's LibMain() function returns 0 (signifying some
  930. logical error during initialization), LoadLibrary() also
  931. returns 0.  Therefore, do not assume that a 0 error code
  932. means the system was out of memory or that the module was
  933. corrupt in some way. 
  934.  
  935.  
  936. ------------------------------------------------------------
  937.  
  938. WDJ SDK Annotation #46
  939. TYPE:       Win3.1
  940. TOPIC:      DdeClientTransaction (3.1)
  941. KEYWORD:    DdeClientTransaction
  942.  
  943. The documentation does not say so, but the cbData argument
  944. (length of data) must include the NULL byte if the data is a
  945. string.  In other words, if lpvData is a string, cbData must
  946. be set to strlen(lpvData)+1.  Otherwise, bad things may
  947. happen in DDEML when you perform an XTYP_POKE or
  948. XTYP_EXECUTE. 
  949.  
  950. Submitted by Mark Reha^
  951. Reference: Microsoft Knowledge Base article Q107387.
  952.  
  953.  
  954. ------------------------------------------------------------
  955.  
  956. WDJ SDK Annotation #47
  957. TYPE:       Win3.1
  958. TOPIC:      WinHelp (3.0)
  959. KEYWORD:    WinHelp
  960.  
  961. The WinHelp() API function normally allows one to execute
  962. macros, jumps, popups, and so on.  However, if WinHelp was
  963. started with WinExec() (i.e.  from Program Manager or File
  964. Manager) instead of the WinHelp() API function, you will not
  965. be able to execute macros or jumps on that help file without
  966. starting up a second instance of the help file using the
  967. WinHelp() API function. 
  968.  
  969. There is one way around this.  You can create a DLL with an
  970. LDLLHandler that gets the callback address for the FAPI()
  971. function from WinHelp.  FAPI() has the same parameters as
  972. the WinHelp() API function except that the first parameters
  973. (HWND) is not in FAPI() (so FAPI() only has 3 parameters). 
  974. The FAPI() function will allow you to execute macros, jumps,
  975. popups, etc regardless of how WinHelp was launched.  For
  976. more information, get the Windows Help Authors Guide from
  977. the MSDN CD-ROM or see Jim Mischel's book "The Developer's
  978. Guide to WINHELP.EXE". 
  979.  
  980. Submitted by Pete Davis
  981.  
  982.  
  983. ------------------------------------------------------------
  984.  
  985. WDJ SDK Annotation #48
  986. TYPE:       Win3.1
  987. TOPIC:      _fpmath (2.x)
  988. KEYWORD:    _fpmath
  989.  
  990. When setting the handler for coprocessor error exceptions
  991. (function 3), the documentation incorrectly says you should
  992. place the address of your exception handler in DS:AX.  The
  993. correct registers to use for this 32-bit address are DX:AX. 
  994.  
  995. Submitted by Manfred Keul
  996.  
  997.  
  998. ------------------------------------------------------------
  999.  
  1000. WDJ SDK Annotation #49
  1001. TYPE:       Win3.1
  1002. TOPIC:      VerQueryValue (3.1)
  1003. KEYWORD:    VerQueryValue
  1004.  
  1005. Amazingly, even though the second parameter to this function
  1006. is declared const (LPCSTR), VerQueryValue() modifies that
  1007. string anyway! Apparently the code replaces a '\' in your
  1008. string with a NULL byte temporarily and then puts it back. 
  1009. This is a bug.  For example, suppose you use a compiler
  1010. option that places constant strings in read-only code
  1011. segments (for Microsoft, "/Gf"; for Borland "-dc").  In that
  1012. case, passing such a constant string as the second argument
  1013. to this function results in a GP fault. 
  1014.  
  1015. Submitted by David Lowndes
  1016.  
  1017.  
  1018. ------------------------------------------------------------
  1019.  
  1020. WDJ SDK Annotation #50
  1021. TYPE:       Win3.1
  1022. TOPIC:      GetProfileString (2.x)
  1023. KEYWORD:    GetProfileString
  1024.  
  1025. This applies to both GetProfileString() and
  1026. GetPrivateProfileString().  If the default value for these
  1027. functions contains trailing blanks and the default value is
  1028. used because the key did not appear in the INI file, Windows
  1029. will null-terminate the string (even though it is declared
  1030. const!) at the first trailing blank.  If that string is a
  1031. literal string and the code is compiled with some
  1032. optimizations then the string will end up in a code segment,
  1033. resulting in a GPF when the API function attempts to modify
  1034. it.
  1035.  
  1036. GetProfileString() and GetPrivateProfileString() also strip
  1037. out any leading spaces, and any leading and trailing quotes
  1038. (single or double quotes).
  1039.  
  1040. Submitted by Michael E. Kropp.^
  1041. Revised by Kai Riihioja
  1042.  
  1043.  
  1044.  
  1045.  
  1046. ------------------------------------------------------------
  1047.  
  1048. WDJ SDK Annotation #50
  1049. TYPE:       Win3.1
  1050. TOPIC:      GetPrivateProfileString (2.x)
  1051. KEYWORD:    GetPrivateProfileString
  1052.  
  1053. This applies to both GetProfileString() and
  1054. GetPrivateProfileString().  If the default value for these
  1055. functions contains trailing blanks and the default value is
  1056. used because the key did not appear in the INI file, Windows
  1057. will null-terminate the string (even though it is declared
  1058. const!) at the first trailing blank.  If that string is a
  1059. literal string and the code is compiled with some
  1060. optimizations then the string will end up in a code segment,
  1061. resulting in a GPF when the API function attempts to modify
  1062. it.
  1063.  
  1064. GetProfileString() and GetPrivateProfileString() also strip
  1065. out any leading spaces, and any leading and trailing quotes
  1066. (single or double quotes).
  1067.  
  1068. Submitted by Michael E. Kropp.^
  1069. Revised by Kai Riihioja
  1070.  
  1071.  
  1072.  
  1073.  
  1074. ------------------------------------------------------------
  1075.  
  1076. WDJ SDK Annotation #51
  1077. TYPE:       Win3.1
  1078. TOPIC:      GetTickCount (2.x)
  1079. KEYWORD:    GetTickCount
  1080.  
  1081. GetTickCount() may return units of milliseconds, but its
  1082. resolution is much worse than one millisecond under Windows
  1083. 3.1.  For more accurate timings, call the function
  1084. timeGetTime(), which is defined in mmsystem.h. 
  1085.  
  1086.  
  1087.  
  1088. ------------------------------------------------------------
  1089.  
  1090. WDJ SDK Annotation #52
  1091. TYPE:       Win3.1
  1092. TOPIC:      GetWinFlags (3.0)
  1093. KEYWORD:    GetWinFlags
  1094.  
  1095. GetWinFlags() can also tell you if your 16-bit Windows 3.1
  1096. application is running under Windows NT:
  1097.  
  1098.     if(GetWinFlags() & 0x04000)^
  1099.         // then we are running under Windows NT^
  1100.  
  1101. Submitted by Paula Tomlinson.^
  1102. Reference: "The Ultimate Windows Version Detector",
  1103. Windows/DOS Developer's Journal, February 1995. 
  1104.  
  1105.  
  1106. ------------------------------------------------------------
  1107.  
  1108. WDJ SDK Annotation #53
  1109. TYPE:       Win3.1
  1110. TOPIC:      KillTimer (2.x)
  1111. KEYWORD:    KillTimer
  1112.  
  1113. Under at least one condition, KillTimer() does not remove a
  1114. pending WM_TIMER message from the message queue as
  1115. documented.  First, understand that Windows just sets a bit
  1116. when a timer fires; it does not generate a WM_TIMER message
  1117. at that time.  A timer message is secretly added to your
  1118. input queue when you call GetMessage() or PeekMessage() and
  1119. a timer event is pending and no other messages are in the
  1120. queue. 
  1121.  
  1122. If you are using a PeekMessage() call with the PM_NOREMOVE
  1123. flag and if the timer bit is on at that point, PeekMessage()
  1124. will place a WM_TIMER message in the queue, but won't remove
  1125. it.  If you then call KillTimer(), it will ensure the timer
  1126. bit is off but won't remove the WM_TIMER message.  The next
  1127. call to GetMessage() or PeekMessage() returns this WM_TIMER
  1128. message.  One workaround is to use code like this to
  1129. terminate a timer:
  1130.  
  1131.     KillTimer (hWnd, ID);^
  1132.     if (LOWORD (GetQueueStatus (QS_TIMER)) & QS_TIMER)^
  1133.          PeekMessage (&msg, hWnd, WM_TIMER, WM_TIMER, PM_REMOVE);^
  1134.  
  1135. Submitted by Mike Mast.
  1136.  
  1137.  
  1138. ------------------------------------------------------------
  1139.  
  1140. WDJ SDK Annotation #54
  1141. TYPE:       Win3.1
  1142. TOPIC:      DEVMODE (3.0)
  1143. KEYWORD:    DEVMODE
  1144.  
  1145. The documentation claims that DMCOLOR_COLOR is defined to be
  1146. 1 and DMCOLOR_MONOCHROME is defined to be 2.  In fact, if
  1147. you look in print.h you discover that the reverse is true. 
  1148.  
  1149. Submitted by Bill Liu.
  1150.  
  1151.  
  1152.  
  1153. ------------------------------------------------------------
  1154.  
  1155. WDJ SDK Annotation #55
  1156. TYPE:       Win3.1
  1157. TOPIC:      EN_CHANGE (2.x)
  1158. KEYWORD:    EN_CHANGE
  1159.  
  1160. The documentation implies this notification only arises from
  1161. actions by the user.  In fact, this notification also arises
  1162. from programmatic changes, such as from sending a WM_SETTEXT
  1163. message to the edit control, or using SetWindowText() (which
  1164. sends a WM_SETTEXT message).  Not knowing this, you might
  1165. code an EN_CHANGE handler that attempts to modify the edit
  1166. control text, resulting in another EN_CHANGE notification --
  1167. an infinite loop!
  1168.  
  1169. Submitted by Scott Smith.
  1170.  
  1171.  
  1172. ------------------------------------------------------------
  1173.  
  1174. WDJ SDK Annotation #56
  1175. TYPE:       Win3.1
  1176. TOPIC:      EnumFonts (2.x)
  1177. KEYWORD:    EnumFonts
  1178.  
  1179. The 3.1 documentation for this function specifies that the
  1180. third argument is of type FONTENUMPROC.  This was true in
  1181. previous versions, but in 3.1 this call is deprecated in
  1182. favour of the new EnumFontFamilies() API function.  The
  1183. definition of the FONTENUMPROC type has been updated to take
  1184. a NEWTEXTMETRIC parameter, and therefore no longer quite
  1185. matches the prototype specified for EnumFonts.  Microsoft
  1186. provids a new type, OLDFONTENUMPROC, which corresponds to
  1187. the STRICT definition of EnumFonts in windows.h, but this is
  1188. not reflected in the documentation.  In other words, if you
  1189. compile with STRICT defined for Windows 3.1 and want to use
  1190. EnumFonts(), make sure the third parameter is of type
  1191. OLDFONTENUMPROC. 
  1192.  
  1193. Submitted by David W. Gillett.
  1194.  
  1195.  
  1196. ------------------------------------------------------------
  1197.  
  1198. WDJ SDK Annotation #57
  1199. TYPE:       Win3.1
  1200. TOPIC:      PtInRect (2.x)
  1201. KEYWORD:    PtInRect
  1202.  
  1203. There is no mention of this, but the rectangle MUST be
  1204. normailized before this function is called.  In other words,
  1205. you have to make sure that lprc->right is greater than
  1206. lprc->left, and that lrpc->bottom is greater than lrpc->top. 
  1207. Otherwise, the point will never be considered inside of the
  1208. rectangle.  By contrast, the function RectInRegion() does
  1209. accept and correctly handle all rectangles, whether
  1210. normalized or not. 
  1211.  
  1212. Submitted by Peter Ritchie.
  1213.  
  1214.  
  1215. ------------------------------------------------------------
  1216.  
  1217. WDJ SDK Annotation #58
  1218. TYPE:       Win3.1
  1219. TOPIC:      SetTimer (2.x)
  1220. KEYWORD:    SetTimer
  1221.  
  1222. The documentation makes it sound like Windows either posts a
  1223. message (if you supply no callback function) or else calls
  1224. your callback function directly when the timer expires.  In
  1225. fact, when the timer fires, Windows sets a bit in your
  1226. message queue which gets transformed into a WM_TIMER message
  1227. by either GetMessage() or PeekMessage() when they find no
  1228. other messages in the input queue.  The WM_TIMER message
  1229. contains the address of your callback function (if any),
  1230. which will be called by DefWindowProc() after the message is
  1231. dispatched to your window.  The key point here is that the
  1232. timers created by SetTimer() are always message based
  1233. (Windows does not call your timer procedure asynchronously)
  1234. and of a lower priority than any other Windows message. 
  1235.  
  1236. Submitted by Alan M. Carroll.
  1237.  
  1238.  
  1239.  
  1240. ------------------------------------------------------------
  1241.  
  1242. WDJ SDK Annotation #59
  1243. TYPE:       Win3.1
  1244. TOPIC:      lstrcpy (2.x)
  1245. KEYWORD:    lstrcpy
  1246.  
  1247. Believe it or not, this function (and apparently other
  1248. similar functions) examine the limit of the selector of the
  1249. output string, and even attempt to silently recover if the
  1250. operation causes a GP fault.  As a consequence, you should
  1251. not count on this function being a real speed demon. 
  1252.  
  1253. Submitted by Vivek Venugopalan
  1254.  
  1255. ------------------------------------------------------------
  1256.  
  1257. WDJ SDK Annotation #60
  1258. TYPE:       Win3.1
  1259. TOPIC:      GetModuleFileName (2.x)
  1260. KEYWORD:    GetModuleFileName
  1261.  
  1262. Windows 3.1 has a bug that causes this function to sometimes
  1263. return relative paths instead of absolute (fully qualified)
  1264. paths.This error occurs if a relative path is specified in
  1265. the PATH variable, and the DLL is implicitly loaded from
  1266. this directory.  For example, if the PATH variable is:
  1267.  
  1268.     PATH=C:\DOS;D:.;C:\UTILS
  1269.  
  1270. and an application running from any other directory but
  1271. "D:.", loads a DLL (test.dll) in "D:." implicitly (since it
  1272. is in the path), then a call to GetModuleFileName() with the
  1273. DLL instance will return "D:.\test.dll". 
  1274.  
  1275. Submitted by V. Ramachandran
  1276. Reference: MSKB PSS ID Number: Q85330.
  1277.  
  1278. ------------------------------------------------------------
  1279.  
  1280. WDJ SDK Annotation #61
  1281. TYPE:       Win3.1
  1282. TOPIC:      CB_GETDROPPEDCONTROLRECT (3.1)
  1283. KEYWORD:    CB_GETDROPPEDCONTROLRECT
  1284.  
  1285. The documentation claims that this function retrieves the
  1286. screen coordinates of the listbox portion of a combo box. 
  1287. In fact, it retrieves the screen coordinates of the
  1288. rectangle that encloses the ENTIRE combo box in its
  1289. dropped-down state.  That means the rectangle retrieved is
  1290. both bit taller and a bit wider than the rectangle that the
  1291. help file claims is returned. 
  1292.  
  1293. Submitted by V. Ramachandran
  1294.  
  1295.  
  1296. ------------------------------------------------------------
  1297.  
  1298. WDJ SDK Annotation #62
  1299. TYPE:       Win3.1
  1300. TOPIC:      NotifyUnRegister (3.1)
  1301. KEYWORD:    NotifyUnRegister
  1302.  
  1303. As the documentation says, you can set the htask argument to
  1304. NULL to refer to the current task.  This is probably not a
  1305. good practice, however.  If more than one application can
  1306. load your DLL, then there is typically some scenario under
  1307. which the task that you called NotifyRegister() for has died
  1308. before you call NotifyUnRegister(), in which case passing
  1309. NULL would refer to the wrong task.  It's probably safer to
  1310. explicitly store that task that was passed to
  1311. NotifyRegister() and make sure you pass the same task to
  1312. NotifyUnregister(). 
  1313.  
  1314. Submitted by Paul Dolphin.
  1315.  
  1316.  
  1317. ------------------------------------------------------------
  1318.  
  1319. WDJ SDK Annotation #63
  1320. TYPE:       Win3.1
  1321. TOPIC:      CreateCompatibleDC (2.x)
  1322. KEYWORD:    CreateCompatibleDC
  1323.  
  1324. You might think from the name that this function returns a
  1325. device context whose attributes are the same as the source
  1326. device context.  In fact, attributes such as the mapping
  1327. mode will be set to their defaults (e.g., the mapping mode
  1328. will always be MM_TEXT) in the returned device context, not
  1329. to the attribute values of the source device context. 
  1330.  
  1331. Submitted by Stuart Patterson^
  1332. Reference: p.  624, "Programming Windows 3.1, 3rd Edition",
  1333. by Charles Petzold
  1334.  
  1335.  
  1336.  
  1337. ------------------------------------------------------------
  1338.  
  1339. WDJ SDK Annotation #64
  1340. TYPE:       Win3.1
  1341. TOPIC:      Device Contexts
  1342. KEYWORD:    Device Contexts
  1343.  
  1344. The help file says CreateCompatibleDC() creates a device
  1345. context that "has the same attributes" as the source device
  1346. context.  In fact, the device context's attributes (such as
  1347. mapping mode) will have their default values, no matter what
  1348. value they had in the source device context. 
  1349.  
  1350. Submitted by Stuart Patterson^
  1351. Reference: p.  624, "Programming Windows 3.1, 3rd Edition",
  1352. by Charles Petzold
  1353.  
  1354. ------------------------------------------------------------
  1355.  
  1356. WDJ SDK Annotation #65
  1357. TYPE:       Win3.1
  1358. TOPIC:      UngetCommChar (2.x)
  1359. KEYWORD:    UngetCommChar
  1360.  
  1361. Do not use this function under Windows 3.1 -- it causes lost
  1362. characters or even GP faults!
  1363.  
  1364. Submitted by Manfred Keul.^
  1365. Reference: Microsoft Knowledge Base article Q100183.
  1366.  
  1367.  
  1368.  
  1369. ------------------------------------------------------------
  1370.  
  1371. WDJ SDK Annotation #66
  1372. TYPE:       Win3.1
  1373. TOPIC:      TabbedTextOut (3.0)
  1374. KEYWORD:    TabbedTextOut
  1375.  
  1376. If a tab character is the last character in the string, then
  1377. all of the area to the next tab stop is filled with the
  1378. current background color.  This may or may not be the
  1379. behavior you want in any given situation. 
  1380.  
  1381. Submitted by Tim English.
  1382.  
  1383. ------------------------------------------------------------
  1384.  
  1385. WDJ SDK Annotation #67
  1386. TYPE:       Win3.1
  1387. TOPIC:      GetRgnBox (3.0)
  1388. KEYWORD:    GetRgnBox
  1389.  
  1390. The documentation claims GetRgnBox() returns COMPLEXREGION
  1391. when the region has overlapping borders.  In fact,
  1392. GetRgnBox() apparently returns COMPLEXREGION if the region
  1393. is simply non-rectangular, whether overlapping borders are
  1394. involved or not. 
  1395.  
  1396. Submitted by Jason Douglas.
  1397.  
  1398. ------------------------------------------------------------
  1399.  
  1400. WDJ SDK Annotation #68
  1401. TYPE:       Win3.1
  1402. TOPIC:      DRAWITEMSTRUCT (3.0)
  1403. KEYWORD:    DRAWITEMSTRUCT
  1404.  
  1405. The itemID field in this structure is set to a negative value
  1406. for an empty listbox or combobox.  Watch out, though -- since
  1407. this field is defined to be unsigned (UINT), a statement like
  1408. this:
  1409.  
  1410.     if(lpdis->itemID >= 0) // if listbox not empty^
  1411.         // ... some code^
  1412.  
  1413. will always evaluate true.  To check for an empty listbox or
  1414. combobox, either cast the field to int or check the high bit:
  1415.  
  1416.     if( (int) lpdis->itemID  >= 0)  // this works correctly^
  1417.         //... some code^
  1418.  
  1419. Submitted by Aaron O'Neil.
  1420.  
  1421.  
  1422. ------------------------------------------------------------
  1423.  
  1424.  
  1425. WDJ SDK Annotation #69
  1426. TYPE:       Win3.1
  1427. TOPIC:      DDEDATA (2.x)
  1428. KEYWORD:    DDEDATA
  1429.  
  1430. In this help topic, the description for the fResponse field
  1431. actually describes the fAckReq field, and vice versa. 
  1432.  
  1433. Submitted by Sudhir Menon.^
  1434. Reference: Microsoft Knowledge Base article Q93372.
  1435.  
  1436. ------------------------------------------------------------
  1437.  
  1438. WDJ SDK Annotation #70
  1439. TYPE:       Win3.1
  1440. TOPIC:      EnableCommNotification (3.1)
  1441. KEYWORD:    EnableCommNotification
  1442.  
  1443. Due to bugs in Windows 3.1, you will probably want to always set
  1444. both cbWriteNotify and cbOutQueue to -1, thus disabling the
  1445. CN_TRANSMIT and CN_RECEIVE notifications.  If you do not set
  1446. them to -1, spurious WM_COMMNOTIFY messages can be sent,
  1447. resulting in a system crash at higher baud rates. 
  1448.  
  1449. Submitted by Manfred Keul.^
  1450. Reference: Microsoft Knowledge Base article Q101420.
  1451.  
  1452.  
  1453.  
  1454. ------------------------------------------------------------
  1455.  
  1456. WDJ SDK Annotation #71
  1457. TYPE:       Win3.1
  1458. TOPIC:      GetMsgProc (3.1)
  1459. KEYWORD:    GetMsgProc
  1460.  
  1461. The help file fails to mention that your hook function gets
  1462. called by PeekMessage(), not just by GetMessage().  The
  1463. documentation also contradicts itself, saying first that wParam
  1464. is undefined and later saying that wParam is NULL.  The
  1465. Microsoft Knowledge Base, on the other hand, reveals that wParam
  1466. contains the PM_ flags that were used in the call to
  1467. PeekMessage(), so your message hook can, for example, determine
  1468. if the message was being removed or not with code like this:
  1469.  
  1470.     if(wParam & PM_REMOVE)^
  1471.         //... then message is being removed^
  1472.     else^
  1473.         //... message is not being removed^
  1474.  
  1475. Note that your hook may want to ignore the message if it is not
  1476. being removed, since your hook will get called again when the
  1477. same message is removed by some future call to GetMessage() or
  1478. PeekMessage(). 
  1479.  
  1480. Submitted by V. Ramachandran.^
  1481. Reference: Microsoft Knowledge Base article Q104068
  1482.  
  1483.  
  1484. ------------------------------------------------------------
  1485.  
  1486. WDJ SDK Annotation #72
  1487. TYPE:       Win3.1
  1488. TOPIC:      GetInstanceData (2.x)
  1489. KEYWORD:    GetInstanceData
  1490.  
  1491. Both the documentation and windows.h declare the second
  1492. parameter as a BYTE*.  Unfortunately, that declaration is only
  1493. correct if you are using a memory model with near data (small or
  1494. medium memory models), and will be incorrect for large or huge
  1495. memory models.  The correct declaration for this argument is
  1496. BYTE NEAR*. 
  1497.  
  1498. Submitted by Martin Cooper.
  1499.  
  1500.  
  1501. ------------------------------------------------------------
  1502.  
  1503. WDJ SDK Annotation #73
  1504. TYPE:       Win3.1
  1505. TOPIC:      MENUITEMTEMPLATE (3.0)
  1506. KEYWORD:    MENUITEMTEMPLATE
  1507.  
  1508. Missing from the list of bits you can turn on in mtOption is
  1509. MF_END (0x0080), which indicates that the item terminates
  1510. the menu.
  1511.  
  1512. Submitted by V. Ramachandran.
  1513.  
  1514.  
  1515.  
  1516. ------------------------------------------------------------
  1517.  
  1518. WDJ SDK Annotation #74
  1519. TYPE:       Win3.1
  1520. TOPIC:      AddAtom (2.x)
  1521. KEYWORD:    AddAtom
  1522.  
  1523. AddAtom() handles strings that begin with "#" specially:
  1524. it expects the string following the "#" to be a string
  1525. of digits, and returns an atom is value is the 16-bit
  1526. binary representation of that string of digits. Unfortunately,
  1527. if your first call to AddAtom() is with a string like "#nondigits",
  1528. it will produce a divide by zero fault. Two workarounds
  1529. are possible: either make sure your first call to AddAtom()
  1530. does not contain such a string, or call InitAtomTable()
  1531. before calling AddAtom() for the first time.
  1532.  
  1533. Submitted by V. Ramachandran.^
  1534. Reference: MSKB PSS ID Number: Q103036
  1535.  
  1536.  
  1537. ------------------------------------------------------------
  1538.  
  1539.  
  1540. WDJ SDK Annotation #75
  1541. TYPE:       Win3.1
  1542. TOPIC:      DCB (2.x)
  1543. KEYWORD:    DCB
  1544.  
  1545. When setting the BaudRate field, do not use the constant
  1546. CBR_14400; Windows 3.1's COMM.DRV has a bug that will produce
  1547. communications problems due to a bad table entry for that
  1548. constant.  Instead, set BaudRate to the integer 14400 to
  1549. communicate at 14400 baud. 
  1550.  
  1551. Submitted by Manfred Keul.^
  1552. Reference: Microsoft Knowledge Base article Q83232.
  1553.  
  1554.  
  1555. ------------------------------------------------------------
  1556.  
  1557. WDJ SDK Annotation #76
  1558. TYPE:       Win3.1
  1559. TOPIC:      RegisterRoutine WinHelp macro
  1560. KEYWORD:    RegisterRoutine WinHelp macro
  1561.  
  1562. The documentation does not reveal how to specify the return type
  1563. of the function. You do this by inserting a type-specifying
  1564. character followed by an equal sign in the third parameter
  1565. string. For example, to register FindWindow() (which takes
  1566. two far strings and returns a 16-bit unsigned integer), you
  1567. might use:
  1568.  
  1569.     RR("USER", "FindWindow", "u=SS");
  1570.  
  1571. Note that if you do not specify a return type when you register
  1572. a function, you cannot use that function in an IfThen or
  1573. IfThenElse macro.
  1574.  
  1575. Submitted by Sudhir Menon.
  1576.  
  1577. ------------------------------------------------------------
  1578.  
  1579. WDJ SDK Annotation #77
  1580. TYPE:       Win3.1
  1581. TOPIC:      RTF Tokens
  1582. KEYWORD:    RTF Tokens
  1583.  
  1584. Strangely, the tokens "emc", "eml", and "emr" are
  1585. misspelled in the online help -- they should be
  1586. "ewc", "ewl", and "ewr", where the "ew" stands for
  1587. Embedded Window. Note that this are not really RTF
  1588. tokens, but literal text. The help compiler scans
  1589. for any text you have entered of the form "{ewx commands}"
  1590. in order to detect embedded window commands. Such text,
  1591. when translated by your word processor into RTF, looks
  1592. like this: "\{ewx commands\}".
  1593.  
  1594. Submitted by John Sawyer.
  1595.  
  1596.  
  1597. ------------------------------------------------------------
  1598.  
  1599. WDJ SDK Annotation #78
  1600. TYPE:       Win3.1
  1601. TOPIC:      WM_ENTERIDLE (2.x)
  1602. KEYWORD:    WM_ENTERIDLE
  1603.  
  1604. Note that you can elect to suppress the WM_ENTERIDLE
  1605. message for a particular modal dialog box by defining
  1606. it with the DS_NOIDLEMSG window style bit.
  1607.  
  1608. Submitted by V. Ramachandran.
  1609.  
  1610.  
  1611. ------------------------------------------------------------
  1612.  
  1613. WDJ SDK Annotation #79
  1614. TYPE:       Win3.1
  1615. TOPIC:      WM_SYSCOMMAND (2.x)
  1616. KEYWORD:    WM_SYSCOMMAND
  1617.  
  1618. You can use this message with SC_MENUKEY to simulate the
  1619. user selecting a menu with an accelerator key.  For example,
  1620. to simulate the user accessing the "File" menu, you might
  1621. use the following code:
  1622.  
  1623. PostMessage(hWnd, WM_SYSCOMMAND, SC_MENUKEY, MAKELPARAM('f',0));
  1624.  
  1625. Submitted by Jay Giganti.
  1626.  
  1627.  
  1628. ------------------------------------------------------------
  1629.  
  1630. WDJ SDK Annotation #80
  1631. TYPE:       Win3.1
  1632. TOPIC:      wsprintf
  1633. KEYWORD:    wsprintf
  1634.  
  1635. The documentation says the second parameter is an LPSTR,
  1636. but it is actually an LPCSTR (and so declared in windows.h),
  1637. so it's safe to use a string constant.
  1638.  
  1639. Submitted by: V. Ramachandran.
  1640.  
  1641.  
  1642. ------------------------------------------------------------
  1643.  
  1644. WDJ SDK Annotation #81
  1645. TYPE:       Win3.1
  1646. TOPIC:      _lread (2.x)
  1647. KEYWORD:    _lread
  1648.  
  1649. If you call _lread() to read a floppy when there is no
  1650. diskette in the drive, Windows puts up a system error
  1651. message box ("Cannot Read from Drive...") with Retry and
  1652. Cancel buttons.  If the user presses the Cancel button,
  1653. _lread() returns a non-negative number, indicating success. 
  1654. It should return HFILE_ERROR instead. 
  1655.  
  1656. To avoid this error, call SetErrorMode(SEM_NOOPENFILEERRORBOX)
  1657. before calling _lread(), then it will correctly return -1 on
  1658. failure. 
  1659.  
  1660. Submitted by: V. Ramachandran.^
  1661. Reference: MSDN PSS ID No. Q111587.
  1662.  
  1663.  
  1664. ------------------------------------------------------------
  1665.  
  1666. WDJ SDK Annotation #82
  1667. TYPE:       Win3.1
  1668. TOPIC:      WM_COMPAREITEM (3.0)
  1669. KEYWORD:    WM_COMPAREITEM
  1670.  
  1671. The documentation for WM_COMPAREITEM says that the parent of
  1672. owner-drawn listboxes with the LBS_SORT (or CBS_SORT) styles
  1673. will get this message in order to determine the relative
  1674. position.  However, Windows will not send the WM_COMPAREITEM
  1675. message if the LBS_HASSTRINGS style bit is set, even if it
  1676. is an owner-drawn listbox with the LBS_SORT style. The same
  1677. is true for comboboxes.
  1678.  
  1679. Submitted by: V. Ramachandran.
  1680.  
  1681.  
  1682. ------------------------------------------------------------
  1683.  
  1684. WDJ SDK Annotation #83
  1685. TYPE:       Win3.1
  1686. TOPIC:      DOCINFO (3.1)
  1687. KEYWORD:    DOCINFO
  1688.  
  1689. The documentation fails to point out that lpszOutput is
  1690. limited to 32 characters, including the null terminating
  1691. byte.  If you use a string longer than that, the trailing
  1692. characters will be ignored.  For example, if you use a
  1693. string containing the too-long path:
  1694.  
  1695.     c:\usr\ts\issues\pending\12345678\abcdefgh.out
  1696.  
  1697. the actual file that gets created will be:
  1698.  
  1699.     c:\usr\ts\issues\pending\123456
  1700.  
  1701. Submitted by V. Ramachandran.
  1702.  
  1703.  
  1704.  
  1705.  
  1706. ------------------------------------------------------------
  1707.  
  1708. WDJ SDK Annotation #84
  1709. TYPE:       Win3.1
  1710. TOPIC:      SetAbortProc function
  1711. KEYWORD:    SetAbortProc
  1712.  
  1713.  
  1714. SetAbortProc() returns a negative value, which is documented
  1715. as indicating failure.  However, the return value from
  1716. SetAbortProc does not indicate success or failure of the
  1717. function, so don't depend on the return value for anything.
  1718.  
  1719. Submitted by:    V. Ramachandran.^
  1720. Reference:    MSDN PSS ID No. Q109540.
  1721.  
  1722.  
  1723. ------------------------------------------------------------
  1724.  
  1725. WDJ SDK Annotation #85
  1726. TYPE:       Win3.1
  1727. TOPIC:      BN_DISABLE (2.x)
  1728. KEYWORD:    BN_DISABLE
  1729.  
  1730. The documentation claims the button sends this notification
  1731. whenever it gets disabled. In fact, Windows 3.1 buttons do
  1732. not appear to ever send this notification!
  1733.  
  1734. Submitted by: V. Ramachandran.
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741. ------------------------------------------------------------
  1742.  
  1743. WDJ SDK Annotation #86
  1744. TYPE:       Win3.1
  1745. TOPIC:      BN_DOUBLECLICKED (2.x)
  1746. KEYWORD:    BN_DOUBLECLICKED
  1747.  
  1748. The documentation fails to point out that this notification
  1749. is only sent for buttons that have the BS_OWNERDRAW or
  1750. BS_RADIOBUTTON styles. No other types of buttons generate
  1751. this notification
  1752.  
  1753. Submitted by: V. Ramachandran.
  1754.  
  1755.  
  1756.  
  1757. ------------------------------------------------------------
  1758.  
  1759. WDJ SDK Annotation #87
  1760. TYPE:       Win3.1
  1761. TOPIC:      WM_DROPFILES (3.1)
  1762. KEYWORD:    WM_DROPFILES
  1763.  
  1764. Documentation for the undocumented handle has since been
  1765. published by Microsoft in Microsoft Systems Journal.  This
  1766. handle points to a structure like this:
  1767.  
  1768. typedef struct {^
  1769.     int     wSize;          // Number of bytes in this structure^
  1770.     POINT   ptMousePos;     // Mouse position^
  1771.     BOOL    fInNonClientArea;// TRUE if mouse was in client area^
  1772.     // Pathnames begin after structure each one zero-terminated^
  1773.     // Zero-length pathname used to indicate the end^
  1774. } DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;^
  1775.  
  1776. The Win32 version of this structure is slightly different.  The
  1777. first field becomes a 4-byte rather than a 2-byte integer, and
  1778. the structure contains an additional BOOL field at the end that
  1779. is TRUE if the pathnames are in Unicode rather than ANSI
  1780. strings. 
  1781.  
  1782. Submitted by V. Ramachandran.^
  1783. Reference:  May/June 1992 Microsoft Systems Journal^
  1784.             February 1994 Microsoft Systems Journal
  1785.  
  1786.  
  1787.  
  1788.  
  1789. ------------------------------------------------------------
  1790.  
  1791. WDJ SDK Annotation #87
  1792. TYPE:       Win32
  1793. TOPIC:      WM_DROPFILES
  1794. KEYWORD:    WM_DROPFILES AND Parameters
  1795.  
  1796. Documentation for the undocumented handle has since been
  1797. published by Microsoft in Microsoft Systems Journal.  This
  1798. handle points to a structure like this:
  1799.  
  1800. typedef struct {^
  1801.     int     wSize;          // Number of bytes in this structure^
  1802.     POINT   ptMousePos;     // Mouse position^
  1803.     BOOL    fInNonClientArea;// TRUE if mouse was in client area^
  1804.     // Pathnames begin after structure each one zero-terminated^
  1805.     // Zero-length pathname used to indicate the end^
  1806. } DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;^
  1807.  
  1808. The Win32 version of this structure is slightly different.  The
  1809. first field becomes a 4-byte rather than a 2-byte integer, and
  1810. the structure contains an additional BOOL field at the end that
  1811. is TRUE if the pathnames are in Unicode rather than ANSI
  1812. strings. 
  1813.  
  1814. Submitted by V. Ramachandran.^
  1815. Reference:  May/June 1992 Microsoft Systems Journal^
  1816.             February 1994 Microsoft Systems Journal
  1817.  
  1818.  
  1819.  
  1820. ------------------------------------------------------------
  1821.  
  1822. WDJ SDK Annotation #88
  1823. TYPE:       Win3.1
  1824. TOPIC:      List box messages 
  1825. KEYWORD:    List box messages 
  1826.  
  1827. Internally, listboxes maintain two 32-bit DWORDs for each
  1828. listbox item.  The first DWORD points to the text for the item
  1829. and the second DWORD contains whatever custom data you would
  1830. like; you can get it via LB_GETITEMDATA or set it via
  1831. LB_SETITEMDATA.  Some messages refer to one or the other of
  1832. these DWORDs, depending on whether the LBS_HASSTRINGS style is
  1833. set:
  1834.  
  1835. Message             LBS_HASSTRINGS?   Refers to:^
  1836. ==========================================================^
  1837. LB_ADDSTRING        Yes             text pointer (lParam)^
  1838. LB_ADDSTRING        No              custom data  (lParam)^
  1839. LB_INSERTSTRING     Yes             text pointer (lParam)^
  1840. LB_INSERTSTRING     No              custom data  (lParam)^
  1841. LB_GETTEXT          Yes             returns text pointer^
  1842. LB_GETTEXT          No              returns custom data^
  1843. LB_GETITEMDATA      either          returns custom data^
  1844. LB_SETITEMDATA      either          sets custom data (lParam)^
  1845. WM_DRAWITEM         either          custom data (in itemData field)^
  1846.  
  1847. In other words, if LBS_HASSTRINGS is not set, you cannot access
  1848. the normal text pointer -- all messages operate on the custom
  1849. data.  But if LBS_HASSTRINGS is set, you can access both the
  1850. normal text as well as the extra DWORD of custom data. 
  1851.  
  1852. Submitted by V. Ramachandran
  1853.  
  1854.  
  1855. ------------------------------------------------------------
  1856.  
  1857. WDJ SDK Annotation #89
  1858. TYPE:       Win3.1
  1859. TOPIC:      SetTimer (2.x)
  1860. KEYWORD:    SetTimer
  1861.  
  1862. Though the documentation does not mention this, you can
  1863. change the timer interval after you create the timer.  If
  1864. you call SetTimer() with a window handle and a timer ID
  1865. equal to an existing timer and specify a different time
  1866. interval, SetTimer() updates the timer to the new time
  1867. interval. 
  1868.  
  1869. Example:
  1870.  
  1871. Use the following line to set a timer to a particular time
  1872. interval. 
  1873.  
  1874. UINT nTimerID = SetTimer (hWnd, TIMER_ID, TIME_INTERVAL, NULL)
  1875.  
  1876. Calling the following line will reset the timer to twice the
  1877. time interval. 
  1878.  
  1879. nTimerID = SetTimer (hWnd, TIMER_ID, 2*TIME_INTERVAL, NULL)
  1880.  
  1881. Submitted by V. Ramachandran.
  1882.  
  1883.  
  1884. ------------------------------------------------------------
  1885.  
  1886. WDJ SDK Annotation #90
  1887. TYPE:       Win3.1
  1888. TOPIC:      TranslateAccelerator (2.x)
  1889. KEYWORD:    TranslateAccelerator
  1890.  
  1891. Contrary to the documentation, both WM_INITMENU and
  1892. WM_INITMENUPOPUP get sent, even if the menu item is disabled,
  1893. and even if the window is minimized and the keystroke matches no
  1894. menu items. 
  1895.  
  1896. Submitted by V. Ramachandran.
  1897.  
  1898.  
  1899. ------------------------------------------------------------
  1900.  
  1901. WDJ SDK Annotation #91
  1902. TYPE:       Win3.1
  1903. TOPIC:      GetPrivateProfileInt (3.0)
  1904. KEYWORD:    GetPrivateProfileInt
  1905.  
  1906. The documentation says you must use a positive integer
  1907. in the range 0 through 32,767 (0x7FFF) for the third
  1908. argument, which is the default value the function returns
  1909. if it cannot locate the desired entry in the .ini file.
  1910. In fact, you can pass any legal integer value for this
  1911. parameter -- it's just that since the function's return
  1912. type is defined to be UINT, you must cast the result to
  1913. int if you want to treat the result as a negative number.
  1914. For example, the following code works correctly, despite
  1915. what the documentation says:
  1916.  
  1917.  int Val = (int)GetPrivateProfileInt(
  1918.      "MyLib", "Debug", -1, "MyLib.ini");
  1919.  if(Val == -1)
  1920.      /* then no such entry found */
  1921.  
  1922.  
  1923. ------------------------------------------------------------
  1924.  
  1925. WDJ SDK Annotation #92
  1926. TYPE:       Win32
  1927. TOPIC:      WM_NOTIFY
  1928. KEYWORD:    WM_NOTIFY AND "See also"
  1929.  
  1930. If your dialog procedure handles a WM_NOTIFY that requires a
  1931. return value, note that you MUST both return a non-zero
  1932. value (to indicate to the dialog manager that you wish to
  1933. specify a return value for the message) AND store the
  1934. desired return value for the message in the window field
  1935. DWL_MSGRESULT.  The standard Windows header file windowsx.h
  1936. provides a macro called SetDlgMsgResult() that makes this
  1937. easy:
  1938.  
  1939.  #include <windowsx.h>
  1940.  //...
  1941.  case WM_NOTIFY  :
  1942.      {
  1943.      NMHDR* Head = (NMHDR*)lParam;
  1944.      if(Head->code == LVN_ENDLABELEDIT)
  1945.          // allow user to edit listview labels
  1946.          return SetDlgMsgResult(Dialog, WM_NOTIFY, TRUE);
  1947.      }
  1948.  
  1949.  
  1950. ------------------------------------------------------------
  1951.  
  1952. WDJ SDK Annotation #92
  1953. TYPE:       Win32
  1954. TOPIC:      LVN_ENDLABELEDIT
  1955. KEYWORD:    LVN_ENDLABELEDIT  AND Parameters
  1956.  
  1957. If your dialog procedure handles a WM_NOTIFY that requires a
  1958. return value (as this one does), note that you MUST both
  1959. return a non-zero value (to indicate to the dialog manager
  1960. that you wish to specify a return value for the message) AND
  1961. store the desired return value for the message in the window
  1962. field DWL_MSGRESULT.  The standard Windows header file
  1963. windowsx.h provides a macro called SetDlgMsgResult() that
  1964. makes this easy:
  1965.  
  1966.  #include <windowsx.h>
  1967.  //...
  1968.  case WM_NOTIFY  :
  1969.      {
  1970.      NMHDR* Head = (NMHDR*)lParam;
  1971.      if(Head->code == LVN_ENDLABELEDIT)
  1972.          // allow user to edit listview labels
  1973.          return SetDlgMsgResult(Dialog, WM_NOTIFY, TRUE);
  1974.      }
  1975.  
  1976.  
  1977. ------------------------------------------------------------
  1978.  
  1979. WDJ SDK Annotation #92
  1980. TYPE:       Win32
  1981. TOPIC:      LVN_BEGINLABELEDIT
  1982. KEYWORD:    LVN_BEGINLABELEDIT AND Parameters
  1983.  
  1984. If your dialog procedure handles a WM_NOTIFY that requires a
  1985. return value (as this one does), note that you MUST both
  1986. return a non-zero value (to indicate to the dialog manager
  1987. that you wish to specify a return value for the message) AND
  1988. store the desired return value for the message in the window
  1989. field DWL_MSGRESULT.  The standard Windows header file
  1990. windowsx.h provides a macro called SetDlgMsgResult() that
  1991. makes this easy:
  1992.  
  1993.  #include <windowsx.h>
  1994.  //...
  1995.  case WM_NOTIFY  :
  1996.      {
  1997.      NMHDR* Head = (NMHDR*)lParam;
  1998.      if(Head->code == LVN_BEGINLABELEDIT)
  1999.          // allow user to edit listview labels
  2000.          return SetDlgMsgResult(Dialog, WM_NOTIFY, FALSE);
  2001.      }
  2002.  
  2003.  
  2004. ------------------------------------------------------------
  2005.  
  2006. WDJ SDK Annotation #93
  2007. TYPE:       Win3.1
  2008. TOPIC:      GetWindowText
  2009. KEYWORD:    GetWindowText 
  2010.  
  2011. GetWindowText() and GetDlgItemText() will not work when
  2012. applied to a standard edit control that belongs to another
  2013. application.  The problem is that GetWindowText() and
  2014. GetDlgItemText() attempt to optimize by directly examining
  2015. the window caption of the target window.  An edit control
  2016. stores an empty string in its caption, not the edit control
  2017. text, so this fails.  You can avoid this bug by sending a
  2018. WM_GETTEXT explicitly:
  2019.  
  2020.  HWND OtherEdit;
  2021.  char Buffer[256];
  2022.  SendMessage(OtherEdit, WM_GETTEXT,
  2023.      sizeof(Buffer), (LPARAM)Buffer);
  2024.  
  2025.  
  2026.  
  2027. ------------------------------------------------------------
  2028.  
  2029. WDJ SDK Annotation #93
  2030. TYPE:       Win3.1
  2031. TOPIC:      GetDlgItemText
  2032. KEYWORD:    GetDlgItemText 
  2033.  
  2034. GetWindowText() and GetDlgItemText() will not work when
  2035. applied to a standard edit control that belongs to another
  2036. application.  The problem is that GetWindowText() and
  2037. GetDlgItemText() attempt to optimize by directly examining
  2038. the window caption of the target window.  An edit control
  2039. stores an empty string in its caption, not the edit control
  2040. text, so this fails.  You can avoid this bug by sending a
  2041. WM_GETTEXT explicitly:
  2042.  
  2043.  HWND OtherEdit;
  2044.  char Buffer[256];
  2045.  SendMessage(OtherEdit, WM_GETTEXT,
  2046.      sizeof(Buffer), (LPARAM)Buffer);
  2047.  
  2048.  
  2049. ------------------------------------------------------------
  2050.  
  2051. WDJ SDK Annotation #94
  2052. TYPE:       Win32
  2053. TOPIC:      LVM_GETCOLUMNWIDTH
  2054. KEYWORD:    LVM_GETCOLUMNWIDTH AND Parameters
  2055.  
  2056. The documentation claims that this message returns the
  2057. column width if successful, "or zero otherwise".  In fact,
  2058. if you specify an invalid column number, this function
  2059. returns garbage.  Therefore, you cannot use this message to
  2060. count the number of columns in a listview control.  The
  2061. associated message, LVM_GETCOLUMN, does correctly return
  2062. zero when passed an invalid column number, so you can use
  2063. LVM_GETCOLUMN to determine the number of columns in a
  2064. listview control. 
  2065.  
  2066. ------------------------------------------------------------
  2067.  
  2068. WDJ SDK Annotation #95
  2069. TYPE:       Win3.1
  2070. TOPIC:      SystemParametersInfo (3.1)
  2071. KEYWORD:    SystemParametersInfo 
  2072.  
  2073. The documentation says that the screen saver time out
  2074. (SPI_GETSCREENSAVETIMEOUT) is specified in milliseconds.  In
  2075. fact, the value returned is in seconds.
  2076.  
  2077. Submitted by: Carlton Guc
  2078.  
  2079.  
  2080.  
  2081. ------------------------------------------------------------
  2082.  
  2083. WDJ SDK Annotation #96
  2084. TYPE:       Win32
  2085. TOPIC:      LVN_ENDLABELEDIT
  2086. KEYWORD:    LVN_ENDLABELEDIT AND Parameters
  2087.  
  2088. The documentation claims that there is no return value for
  2089. this message.  In fact, you should return FALSE if you want
  2090. to reject the user's editing, or TRUE if you want to allow
  2091. the changes to the listview item.  If you are handling this
  2092. notification inside a dialog procedure, remember that you
  2093. must return a non-zero result AND store the message result
  2094. (either TRUE or FALSE) in DWL_MSGRESULT, using either
  2095. SetWindowLong() or the SetDlgMsgResult() macro (defined in
  2096. windowsx.h). 
  2097.  
  2098. Submitted by: Poul A. Costinsky
  2099.  
  2100.  
  2101. ------------------------------------------------------------
  2102.  
  2103. WDJ SDK Annotation #98
  2104. TYPE:       Win32
  2105. TOPIC:      RegSetValueEx
  2106. KEYWORD:    RegSetValueEx AND "See also"
  2107.  
  2108. For string-based data types, such as REG_SZ, this function
  2109. behaves differently under Win95 and NT.  Under Win95, if you
  2110. pass a value of "abcd" and a length of 4, the function will
  2111. actually append a null byte, and if you retrieve the value
  2112. later, you will find it has a length of 5.  Under NT, this
  2113. function stores exactly what you tell it to store. 
  2114.  
  2115. Submitted by Paula Tomlinson.
  2116.  
  2117. ------------------------------------------------------------
  2118.  
  2119. WDJ SDK Annotation #97
  2120. TYPE:       Win32
  2121. TOPIC:      LVN_ITEMCHANGING
  2122. KEYWORD:    LVN_ITEMCHANGING AND Parameters
  2123.  
  2124. The documentation incorrectly claims that you have to return
  2125. TRUE to allow the change, or FALSE to prevent it.  In fact,
  2126. you have to return FALSE to allow the change or TRUE to
  2127. prevent it. 
  2128.  
  2129. Submitted by V. Ramachandran.
  2130.  
  2131.  
  2132.  
  2133. ------------------------------------------------------------
  2134.  
  2135. WDJ SDK Annotation #99
  2136. TYPE:       Win32
  2137. TOPIC:      LV_DISPINFO
  2138. KEYWORD:    LV_DISPINFO AND Parameters
  2139.  
  2140. The documentation says you can set the LVIF_DI_SETITEM flag
  2141. in the mask member to have Windows store the string and not
  2142. ask for it again.  It fails to point out that this only
  2143. works for subitem 0 (the first column), so you would still
  2144. have to handle requests for the text of the other columns. 
  2145.  
  2146. Submitted by V. Ramachandran.
  2147.  
  2148.  
  2149. ------------------------------------------------------------
  2150.  
  2151. WDJ SDK Annotation #100
  2152. TYPE:       Win32
  2153. TOPIC:      LVM_EDITLABEL
  2154. KEYWORD:    LVM_EDITLABEL AND Parameters
  2155.  
  2156. Note that the listview control implements in-place editing
  2157. by creating an edit control on the fly.  Unfortunately, it
  2158. assigns that edit control a child ID of IDOK, which means
  2159. that the parent of the listview control will receive edit
  2160. control notifications that it might not expect.  For
  2161. example, if your listview control is in a dialog box, and
  2162. your dialog procedure contains code like this:
  2163.  
  2164.  // inside WM_COMMAND handler...
  2165.  if(ControlId == IDOK)
  2166.      EndDialog(Dialog, TRUE);
  2167.  
  2168. Then it may terminate the dialog when the user starts
  2169. editing a listview item (since the transient edit control
  2170. will send notifications like EN_CHANGE, with a control ID of
  2171. IDOK). The above code should read:
  2172.  
  2173.  // inside WM_COMMAND handler...
  2174.  if(ControlId == IDOK && NotifyCode == BN_CLICKED)
  2175.      EndDialog(Dialog, TRUE);
  2176.  
  2177. to be safe.
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184. ------------------------------------------------------------
  2185.  
  2186. WDJ SDK Annotation #101
  2187. TYPE:       Win3.1
  2188. TOPIC:      GetWindowTextLength (2.x)
  2189. KEYWORD:    GetWindowTextLength
  2190.  
  2191. Due to a bug in Windows 3.1, both GetWindowTextLength() and
  2192. WM_GETTEXTLENGTH return -1 if you use it on a combobox of
  2193. style CBS_DROPDOWNLIST. 
  2194.  
  2195. Submitted by Mircea Neacsu
  2196.  
  2197.  
  2198.  
  2199. ------------------------------------------------------------
  2200.  
  2201. WDJ SDK Annotation #102
  2202. TYPE:       Win32
  2203. TOPIC:      LB_ADDSTRING
  2204. KEYWORD:    LB_ADDSTRING AND Parameters
  2205.  
  2206. If you are planning to add a large number (more than 100) of
  2207. strings by calling LB_ADDSTRING, LB_INSERTSTRING, LB_DIR, or
  2208. LB_ADDFILE, consider first sending the new Win32 message
  2209. LB_INITSTORAGE to give the listbox a chance to preallocate
  2210. memory, thus speeding up the process. 
  2211.  
  2212. Submitted by V. Ramachandran.
  2213.  
  2214.  
  2215. ------------------------------------------------------------
  2216.  
  2217. WDJ SDK Annotation #102
  2218. TYPE:       Win32
  2219. TOPIC:      LB_ADDSTRING
  2220. KEYWORD:    LB_ADDSTRING AND Parameters
  2221.  
  2222. If you are planning to add a large number (more than 100) of
  2223. strings by calling LB_ADDSTRING, LB_INSERTSTRING, LB_DIR, or
  2224. LB_ADDFILE, consider first sending the new Win32 message
  2225. LB_INITSTORAGE to give the listbox a chance to preallocate
  2226. memory, thus speeding up the process. 
  2227.  
  2228. Submitted by V. Ramachandran.
  2229.  
  2230.  
  2231. ------------------------------------------------------------
  2232.  
  2233. WDJ SDK Annotation #103
  2234. TYPE:       Win32
  2235. TOPIC:      LoadString
  2236. KEYWORD:    LoadString AND "See also"
  2237.  
  2238. Even though resource strings are stored as Unicode for both
  2239. Win95 and NT programs, Win95 does not provide an
  2240. implementation of the Unicode version of LoadString()
  2241. (LoadStringW()).  This usually trips up NT programmers who
  2242. want to create a single .exe for both operating systems and
  2243. yet still use Unicode under NT.  In that case, you must at
  2244. runtime detect that you are running under Win95 and, in that
  2245. case, explicitly call LoadStringA().  Otherwise, if you have
  2246. compiled with _UNICODE defined, LoadString() will expand
  2247. into LoadStringW(), which is just a stub that fails under
  2248. Win95. 
  2249.  
  2250. Submitted by Paula Tomlinson.
  2251.  
  2252.  
  2253.  
  2254. ------------------------------------------------------------
  2255.  
  2256. WDJ SDK Annotation #104
  2257. TYPE:       Win32
  2258. TOPIC:      LVN_DELETEITEM
  2259. KEYWORD:    LVN_DELETEITEM AND Parameters
  2260.  
  2261. The documentation implies that this notification
  2262. arrives after the item is deleted. In fact, it
  2263. arrives before the item is deleted from the listview
  2264. control.
  2265.  
  2266. Submitted by V. Ramachandran.
  2267.  
  2268.  
  2269. ------------------------------------------------------------
  2270.  
  2271. WDJ SDK Annotation #105
  2272. TYPE:       Win32
  2273. TOPIC:      IsWindow
  2274. KEYWORD:    IsWindow AND Parameters
  2275.  
  2276. The documentation claims this function returns TRUE if the
  2277. given handle is a valid window handle.  That was true under
  2278. Windows 3.x and is true under Windows NT, but Windows 95
  2279. returns a large non-zero value that is not equal to 1 (nor
  2280. is it equal to the window handle). In an un-indexed help
  2281. topic in the initial Win95 SDK, Microsoft reveals that
  2282. Win95 functions with BOOL return types are only guaranteed
  2283. to return non-zero when the documentation claims they
  2284. return TRUE. Windows NT appears to behave as documented.
  2285.  
  2286. Submitted by: David Lowndes
  2287.  
  2288.  
  2289. ------------------------------------------------------------
  2290.  
  2291. WDJ SDK Annotation #105
  2292. TYPE:       Win32
  2293. TOPIC:      GetClientRect
  2294. KEYWORD:    GetClientRect AND "See also"
  2295.  
  2296. The documentation claims this function returns TRUE if the
  2297. given handle is a valid window handle.  That was true under
  2298. Windows 3.x and is true under Windows NT, but Windows 95
  2299. returns a large non-zero value that is not equal to 1 (nor
  2300. is it equal to the window handle). In an un-indexed help
  2301. topic in the initial Win95 SDK, Microsoft reveals that
  2302. Win95 functions with BOOL return types are only guaranteed
  2303. to return non-zero when the documentation claims they
  2304. return TRUE. Windows NT appears to behave as documented.
  2305.  
  2306. Submitted by: Ron Scott
  2307.  
  2308.  
  2309. ------------------------------------------------------------
  2310.  
  2311. WDJ SDK Annotation #106
  2312. TYPE:       Win32
  2313. TOPIC:      WM_GETDLGCODE
  2314. KEYWORD:    WM_GETDLGCODE AND Parameters
  2315.  
  2316. The documentation WM_GETDLGCODE states that this message has
  2317. no parameters. But the truth is that if the user presses a
  2318. key, lParam will contain a pointer to a MSG structure
  2319. containing information about the event that made Windows send
  2320. the WM_GETDLGCODE message.  This is indirectly documented in
  2321. windowsx.h, where the HANDLE_WM_GETDLGCODE() macro passes
  2322. two arguments to the handler: the window handle and (MSG
  2323. FAR*)(lParam). 
  2324.  
  2325. Submitted by: Patrick Tennberg
  2326. Reference: Microsoft Knowledge Base article Q83302
  2327.  
  2328.  
  2329.  
  2330. ------------------------------------------------------------
  2331.  
  2332. WDJ SDK Annotation #107
  2333. TYPE:       Win32
  2334. TOPIC:      DBT_DEVICEQUERYREMOVE
  2335. KEYWORD:    DBT_DEVICEQUERYREMOVE AND Parameters
  2336.  
  2337. The documentation incorrectly says that you should return
  2338. FALSE if you want to veto the device removal.  In fact, you
  2339. have to return BROADCAST_QUERY_DENY; returning FALSE will
  2340. allow the device removal to proceed. 
  2341.  
  2342. Submitted by Paula Tomlinson.
  2343.  
  2344.  
  2345. ------------------------------------------------------------
  2346.  
  2347. WDJ SDK Annotation #108
  2348. TYPE:       Win3.1
  2349. TOPIC:      LZOpenFile
  2350. KEYWORD:    LZOpenFile 
  2351.  
  2352.  
  2353. However, if lpszFile contains only a filename and extension
  2354. (i.e.  no path is specified), then LZOpenFile() use the same
  2355. searching logic as OpenFile().  If no file with the matching
  2356. name (and extension) is found, then it searches for the
  2357. compressed filename.  The compressed file has a _ as the
  2358. last character (e.g., the compressed version of "readme.txt"
  2359. is "readme.tx_").  Therefore if you use LZOpenFile() to open
  2360. a file called "readme.txt", it searches as follows:
  2361.  
  2362.  1) it looks for "readme.txt" using the same search
  2363.     algorithm as OpenFile().
  2364.  2) if the file was not found, it uses the same
  2365.     algorithm to search for "readme.tx_".
  2366.  
  2367. That means LZOpenFile() might open a "readme.tx_" file from
  2368. a directory other than the one you expected.  Even if you
  2369. specify the complete filename (such as
  2370. "c:\demo\readme.txt"), LZOpenFile() first searches for the
  2371. specified file, and if the specified filename is not found,
  2372. it searches for the compressed file in the same directory
  2373. ("c:\demo\readme.tx_"). 
  2374.  
  2375. Submitted by V. Ramachandran.
  2376.  
  2377.  
  2378. ------------------------------------------------------------
  2379.  
  2380. WDJ SDK Annotation #109
  2381. TYPE:       Win32
  2382. TOPIC:      SetCapture
  2383. KEYWORD:    SetCapture AND Parameters
  2384.  
  2385. This help topic does not document the fact that when the
  2386. mouse is captured, menu hotkeys (for example, Alt+F for
  2387. accessing the File menu) and other keyboard accelerators do
  2388. not work (ex: Alt+F4).  This is because DefWindowProc()
  2389. handles the WM_SYSCHAR and WM_SYSCOMMAND messages
  2390. differently if the mouse has been captured (by any window). 
  2391.  
  2392. DefWindowProc() processes the WM_SYSCHAR message to check if
  2393. the pressed key is a menu hotkey (Alt+F for example).  If it
  2394. is, then it causes the menu to drop down.  However, if the
  2395. mouse is captured, it does not do the above action. 
  2396. Whenever DefWindowProc() sees a WM_SYSCOMMAND and finds that
  2397. the mouse is captured, then it does nothing. 
  2398.  
  2399. Submitted by V. Ramachandran.
  2400.  
  2401.  
  2402.  
  2403. ------------------------------------------------------------
  2404.  
  2405. WDJ SDK Annotation #110
  2406. TYPE:       Win32
  2407. TOPIC:      RegCreateKey
  2408. KEYWORD:    RegCreateKey AND "See also"
  2409.  
  2410. The documentation for RegCreateKey(), RegCreateKeyEx(),
  2411. RegOpenKey(), and RegOpenKeyEx() all list several predefined
  2412. handles you can use, such as HKEY_CURRENT_USER.  However,
  2413. they fail to document the predefined key
  2414. HKEY_CURRENT_CONFIG, which has a structure similar to the
  2415. registry tree under HKEY_LOCAL_MACHINE, but is for storing
  2416. information specific to the current hardware profile. 
  2417.  
  2418. Submitted by Paula Tomlinson.
  2419.  
  2420.  
  2421.  
  2422.  
  2423.  
  2424. ------------------------------------------------------------
  2425.  
  2426. WDJ SDK Annotation #111
  2427. TYPE:       Win32
  2428. TOPIC:      CreateFile
  2429. KEYWORD:    CreateFile AND "See also"
  2430.  
  2431. The documentation claims CreateFile() returns a handle that
  2432. can be used to access the object.  However, under both NT
  2433. and Win95, CreateFile() will appear to succeed and return a
  2434. valid handle if you attempt to open a file with
  2435. GENERIC_WRITE permissions on a read-only medium (e.g.,
  2436. protected floppy or CD-ROM).  If you then try to perform a
  2437. write with the returned handle, that will fail. 
  2438.  
  2439.  
  2440. Submitted by: David Lowndes
  2441.  
  2442.  
  2443.  
  2444.  
  2445. ------------------------------------------------------------
  2446.  
  2447. WDJ SDK Annotation #112
  2448. TYPE:       Win32
  2449. TOPIC:      GetWindowText
  2450. KEYWORD:    GetWindowText AND "See Also"
  2451.  
  2452. The third argument is the "maximum numbers of characters to
  2453. copy".  It may not be clear that this number must include
  2454. the NULL byte so, for example, it never makes sense to set
  2455. this argument to 1 since all you could get back is a NULL
  2456. byte.  If you want to use GetWindowText() to retrieve a
  2457. single character (e.g., from an edit control), you would
  2458. have to specify a length of 2 -- one for the character and
  2459. one for the terminating NULL byte. 
  2460.  
  2461. Submitted by: Tony Yuricich
  2462.  
  2463.  
  2464.  
  2465.  
  2466. ------------------------------------------------------------
  2467.  
  2468. WDJ SDK Annotation #113
  2469. TYPE:       Win32
  2470. TOPIC:      keybd_event
  2471. KEYWORD:    keybd_event AND "See also"
  2472.  
  2473. You can use this function to toggle keys such as the Caps
  2474. Lock, Scroll Lock, and Num Lock.  Unfortunately, though
  2475. toggling these three keys works correctly under NT, you
  2476. cannot use this function to toggle the Num Lock key under
  2477. Win95. 
  2478.  
  2479.  
  2480.  
  2481. ------------------------------------------------------------
  2482.  
  2483. WDJ SDK Annotation #114
  2484. TYPE:       Win3.1
  2485. TOPIC:      WM_CTLCOLOR (2.x)
  2486. KEYWORD:    WM_CTLCOLOR 
  2487.  
  2488.  
  2489.  
  2490. The documentation incorrectly states that "the return value
  2491. from this message has no effect on a button with the
  2492. BS_PUSHBUTTON or BS_DEFPUSHBUTTON style." In fact, returning
  2493. a brush handle in response to this message appears to
  2494. determine the color of the pushbutton window background,
  2495. which is visible as the tiny areas in the corners of the
  2496. pushbutton window.  Note that under Windows 95, pushbuttons
  2497. fill the entire client area of their windows, thus hiding
  2498. the window background from view. 
  2499.  
  2500. Submitted by: Forest Wilkinson
  2501.  
  2502.  
  2503.  
  2504.  
  2505. ------------------------------------------------------------
  2506.  
  2507.  
  2508.  
  2509. WDJ SDK Annotation #115
  2510. TYPE:       Win32
  2511. TOPIC:      GlobalDeleteAtom
  2512. KEYWORD:    GlobalDeleteAtom AND "See also"
  2513.  
  2514. The documentation for GlobalDeleteAtom states:
  2515.  
  2516.   "The only way to ensure that an atom has been deleted from the 
  2517. atom table is to call this function repeatedly until it fails."
  2518.  
  2519. Unfortunately, a 32-bit program running under Win NT 3.51 never fails,
  2520. making for an infinite loop (Windows 95 functions as documented).
  2521. Microsoft says this may be fixed in the next release (NT 4.0).
  2522.  
  2523. Submitted by Ken Brown
  2524.  
  2525.  
  2526. ------------------------------------------------------------
  2527.  
  2528. WDJ SDK Annotation #116
  2529. TYPE:       Win32
  2530. TOPIC:      LB_ADDSTRING
  2531. KEYWORD:    LB_ADDSTRING AND "See also"
  2532.  
  2533. If your listbox has the WS_HSCROLL style, and if you are
  2534. adding a string wider than the listbox, you may have to send
  2535. a LB_SETHORIZONTALEXTENT message to make the horizontal
  2536. scrollbar appear.  The listbox does not automatically check
  2537. each newly added string and add the horizontal scrollbar
  2538. when a too-wide string is added or inserted. 
  2539.  
  2540.  
  2541.  
  2542.  
  2543. ------------------------------------------------------------
  2544.  
  2545.  
  2546.  
  2547. WDJ SDK Annotation #117
  2548. TYPE:       Win32
  2549. TOPIC:      LB_DIR
  2550. KEYWORD:    LB_DIR AND "See also"
  2551.  
  2552. If you pass a long filename to LB_DIR, it works
  2553. under NT 3.51, but fails under Win95 because it
  2554. relies on the 16-bit listbox which was not changed
  2555. to handle long filenames. You can avoid the error
  2556. by first translating the filename to a short filename
  2557. by calling GetShortPathName(). The LB_DIR will not
  2558. fail, but it will still display only the short versions
  2559. of any long filenames in the subdirectory.
  2560.  
  2561. Reference: Microsoft Knowledge Base article Q131286
  2562.  
  2563.  
  2564.  
  2565.  
  2566. ------------------------------------------------------------
  2567.  
  2568.  
  2569.  
  2570. WDJ SDK Annotation #118
  2571. TYPE:       Win32
  2572. TOPIC:      ReadFile
  2573. KEYWORD:    ReadFile AND "See also"
  2574.  
  2575. The documentation correctly points out that Win95
  2576. does not support OVERLAPPED I/O. However, it incorrectly
  2577. states that you must pass a pointer to a structure of
  2578. type OVERLAPPED if the file was created (or opened)
  2579. with the flag FILE_FLAG_OVERLAPPED. In fact, if you
  2580. pass a pointer (rather than NULL) under Windows 95,
  2581. ReadFile() returns FALSE, and GetLastError() returns
  2582. ERROR_INVALID_PARAMETER, whether or not the file
  2583. was created/opened with the FILE_FLAG_OVERLAPPED
  2584. flag. That means that if you want to code a call
  2585. to ReadFile() that works correctly for both
  2586. synchronous and asynchronous I/O, you must detect
  2587. at runtime that you're running under Win95 and
  2588. treat that case differently.
  2589.  
  2590.  
  2591.  
  2592. -----------------------------------------------------------------------
  2593.  
  2594.  
  2595. WDJ SDK Annotation #119
  2596. TYPE:       Win32
  2597. TOPIC:      WinMain
  2598. KEYWORD:    WinMain AND "See also"
  2599.  
  2600. Note that the string passed in lpCmdLine is not the same as
  2601. the string returned by GetCommandLine().  The string in
  2602. lpCmdLine contains the command line arguments only, but
  2603. GetCommandLine() returns the program name followed by the
  2604. arguments. 
  2605.  
  2606. If you specify the following command: 'winword abc.doc', and
  2607. winword exists in d:\msoffice\winword.exe, lpCmdLine will
  2608. contain 'abc.doc', while GetCommandLine will return
  2609. '"d:\msoffice\winword.exe" abc.doc' Note the double quotes
  2610. around the exe name. 
  2611.  
  2612. Submitted by Phil Rodgers.
  2613.  
  2614. ----------------------------------------------------------------------
  2615.  
  2616.  
  2617. WDJ SDK Annotation #119
  2618. TYPE:       Win32
  2619. TOPIC:      GetCommandLine
  2620. KEYWORD:    GetCommandLine AND "See also"
  2621.  
  2622. Note that the string passed in the lpCmdLine parameter to
  2623. WinMain is not the same as the string returned by
  2624. GetCommandLine().  GetCommandLine() returns the complete
  2625. program name enclosed in double quotes, followed by the
  2626. arguments; whereas the lpCmdLine parameter of WinMain
  2627. contains the command line arguments only. 
  2628.  
  2629. If you specify the following command: 'winword abc.doc', and
  2630. winword exists in d:\msoffice\winword.exe, lpCmdLine will
  2631. contain 'abc.doc', while GetCommandLine will return
  2632. '"d:\msoffice\winword.exe" abc.doc' Note the double quotes
  2633. around the exe name. 
  2634.  
  2635. Submitted by Phil Rodgers.
  2636.  
  2637. ----------------------------------------------------------------------
  2638.  
  2639. WDJ SDK Annotation #120
  2640. TYPE:       Win32
  2641. TOPIC:      ShellAbout
  2642. KEYWORD:    ShellAbout AND "See also"
  2643.  
  2644. The documentation says that in Windows 95 ShellAbout will
  2645. prepend "Microsoft Windows" to the title of the application. 
  2646. This is not true.  Actually, this function prepends only
  2647. "Microsoft", so if your app is called "MyApp", the title
  2648. will read "Microsoft MyApp". 
  2649.  
  2650. Submitted by Luis A. Ramos.
  2651.  
  2652. ----------------------------------------------------------------------
  2653.  
  2654. WDJ MFC Annotation #121
  2655. TYPE:       MFC 4
  2656. TOPIC:      CPropertySheet::SetTitle
  2657. KEYWORD:    SetTitle AND CPropertySheet
  2658.  
  2659. The parameters to this function are interchanged: it should
  2660. actually read:
  2661.  
  2662. void SetTitle (LPCTSTR lpszText, UINT nStyle);
  2663.  
  2664. Submitted by Margaret M. O'Connell.
  2665.  
  2666. ----------------------------------------------------------------------
  2667.  
  2668. WDJ MFC Annotation #122
  2669. TYPE:       MFC 1.5x
  2670. TOPIC:      CCmdTarget::GetIDispatch
  2671. KEYWORD:    GetIDispatch AND CCmdTarget
  2672.  
  2673. The MFC 1.5x documentation incorrectly states that this
  2674. function takes no parameters. It should read:
  2675.  
  2676.  LPDISPATCH GetIDispatch (BOOL bAddRef)
  2677.  bAddRef - specifies whether to increment
  2678.            the reference count for the object.
  2679.  
  2680. This has been corrected in the MFC 4.0 documentation.
  2681.  
  2682. Submitted by V.Ramachandran.
  2683.  
  2684. ----------------------------------------------------------------------
  2685.  
  2686. WDJ SDK Annotation #123
  2687. TYPE:       Win16
  2688. TOPIC:      LB_SELECTSTRING
  2689. KEYWORD:    LB_SELECTSTRING
  2690.  
  2691. win31wh.hlp fails to mention that this message works only
  2692. with single select listboxes.  For multi-select listboxes it
  2693. returns LB_ERR. 
  2694.  
  2695. Submitted by Dino Esposito.
  2696.  
  2697. ----------------------------------------------------------------------
  2698.  
  2699.  
  2700.  
  2701. WDJ SDK Annotation #124
  2702. TYPE:       Win32
  2703. TOPIC:      AdjustWindowRect
  2704. KEYWORD:    AdjustWindowRect AND "See also"
  2705.  
  2706. The documentation for AdjustWindowRect() and
  2707. AdjustWindowRectEx() has a number of problems. 
  2708.  
  2709. 1.  Though the documentation says that window titles and
  2710. borders are not taken into account, the function does
  2711. account for these styles. 
  2712.  
  2713. 2.  Add 1 to the rect.bottom returned by this function. 
  2714. There is a one-off error in the y direction. 
  2715.  
  2716. 3.  The meaning of the rect parameter is not well explained. 
  2717. The input to AdjustWindowRectEx is the window coordinates of
  2718. the top-left and bottom-right corners of the desired client
  2719. area.  AdjustWindowRectEx inflates the specified rectangle
  2720. to include the caption, border and other non-client objects
  2721. specified by the style parameter. 
  2722.  
  2723.  
  2724. Reference: MSDN Dr.GUI #10 - Calculated Client Window Size.
  2725.  
  2726. Submitted by Etay Szekely.
  2727.  
  2728. ----------------------------------------------------------------------
  2729.  
  2730.  
  2731. WDJ SDK Annotation #124
  2732. TYPE:       Win32
  2733. TOPIC:      AdjustWindowRectEx
  2734. KEYWORD:    AdjustWindowRectEx AND "See also"
  2735.  
  2736. The documentation for AdjustWindowRect() and
  2737. AdjustWindowRectEx() has a number of problems. 
  2738.  
  2739. 1.  Though the documentation says that window titles and
  2740. borders are not taken into account, they function does
  2741. account for these styles. 
  2742.  
  2743. 2.  Add 1 to the rect.bottom returned by this function. 
  2744. There is a one-off error in the y direction. 
  2745.  
  2746. 3.  The meaning of the rect parameter is not well explained. 
  2747. The input to AdjustWindowRectEx is the window coordinates of
  2748. the top-left and bottom-right corners of the desired client
  2749. area.  AdjustWindowRectEx inflates the specified rectangle
  2750. to include the caption, border and other non-client objects
  2751. specified by the style parameter. 
  2752.  
  2753.  
  2754. Reference: MSDN Dr.GUI #10 - Calculated Client Window Size.
  2755.  
  2756. Submitted by Etay Szekely.
  2757.  
  2758.  
  2759. ----------------------------------------------------------------------
  2760.  
  2761. WDJ MFC Annotation #125
  2762. TYPE:       MFC 3.1 and 3.2
  2763. TOPIC:      CImageList::DeleteObject
  2764. KEYWORD:    DeleteObject AND "See also" NOT HRESULT
  2765.  
  2766. VC++ 2.1 and 2.2 help files incorrectly documented this
  2767. function to delete image lists, while it actually never
  2768. existed.  The correct function to delete an image list is
  2769. CImageList::DeleteImageList(); it returns non-zero if
  2770. successful and zero if it fails.
  2771.  
  2772. This error is corrected in the VC++ 4.0 documentation.
  2773.  
  2774. Submitted by Barry Tannenbaum.
  2775.  
  2776. ----------------------------------------------------------------------
  2777.  
  2778. WDJ SDK Annotation #126
  2779. TYPE:       Win32
  2780. TOPIC:      AVIFileOpen
  2781. KEYWORD:    AVIFileOpen AND "See also"
  2782.  
  2783. The documentation specifies that using the OF_CREATE flag
  2784. will cause an existing file to be truncated to zero length. 
  2785. In reality, it has no effect: the file length remains the
  2786. same, and the old data is intact once the file is closed. 
  2787.  
  2788. Submitted by Tim Lesher.
  2789.  
  2790. ----------------------------------------------------------------------
  2791.  
  2792. WDJ SDK Annotation #127
  2793. TYPE:       Win16
  2794. TOPIC:      CBTProc
  2795. KEYWORD:    CBTProc
  2796.  
  2797. The CBTProc documentation fails to mention that you can
  2798. return 0 to allow the operation and 1 to prevent it for
  2799. HCBT_SETFOCUS notification also.  The documentation has been
  2800. corrected in the Win32 help file. 
  2801.  
  2802. Submitted by V.Ramachandran.
  2803.  
  2804.  
  2805. ----------------------------------------------------------------------
  2806.  
  2807. WDJ SDK Annotation #128
  2808. TYPE:       Win32
  2809. TOPIC:      GetDialogBaseUnits
  2810. KEYWORD:    GetDialogBaseUnits AND "See also"
  2811.  
  2812. GetDialogBaseUnits() does not return correct dialog base
  2813. units if the dialog is not using the system font.  Use the
  2814. following function instead:
  2815.  
  2816.  DWORD WDJ_GetDialogBaseUnits (HWND Dialog)
  2817.  {
  2818.     int BaseX, BaseY;
  2819.     RECT R;
  2820.     SetRect (&R, 0, 0, 4, 8);
  2821.     MapDialogRect (Dialog, &R);
  2822.     BaseX = R.right;
  2823.     BaseY = R.bottom;
  2824.     return (DWORD)MAKELONG (BaseX, BaseY);
  2825.  }
  2826.  
  2827. Reference: p54, January 1996 Windows Developer's Journal.
  2828.  
  2829.  
  2830. ----------------------------------------------------------------------
  2831.  
  2832. WDJ SDK Annotation #129
  2833. TYPE:       Win32
  2834. TOPIC:      GetShortPathName
  2835. KEYWORD:    GetShortPathName AND "See also"
  2836.  
  2837. The documentation fails to mention that this function returns an error
  2838. if the specified long path (first parameter) is invalid. 
  2839.  
  2840. Submitted by Ken Brown.
  2841.  
  2842. ----------------------------------------------------------------------
  2843.  
  2844. WDJ MFC Annotation #130
  2845. TYPE:       MFC
  2846. TOPIC:      CCheckListBox::Create
  2847. KEYWORD:    CCheckListBox::Create AND "See also"
  2848.  
  2849. The documentation mentions that the dwStyle parameter could be any 
  2850. of the specified listbox styles. However, the dwStyle parameter should 
  2851. NOT be LBS_MULTICOLUMN or LBS_USETABSTOPS. Morever, you need to specify
  2852. LBS_OWNERDRAWFIXED and LBS_HASSTRINGS. You can specify
  2853. LBS_OWNERDRAWVARIABLE instead of LBS_OWNERDRAWFIXED, but then you need to
  2854. override CCheckListBox::DrawItem, otherwise the debug version will ASSERT.
  2855.  
  2856. Submitted by Sudhir Menon.
  2857.  
  2858. ----------------------------------------------------------------------
  2859.  
  2860. WDJ SDK Annotation #131
  2861. TYPE:       Win32
  2862. TOPIC:      TBBUTTON
  2863. KEYWORD:    TBBUTTON AND "See also"
  2864.  
  2865. The structure is actually defined as follows in commctrl.h. Under Win32
  2866. 2 extra padding bytes are added.
  2867.  
  2868.  typedef struct _TBBUTTON {
  2869.     int iBitmap;
  2870.     int idCommand;
  2871.     BYTE fsState;
  2872.     BYTE fsStyle;
  2873.  #ifdef _WIN32
  2874.     BYTE bReserved[2];
  2875.  #endif
  2876.     DWORD dwData;
  2877.     int iString;
  2878.  } TBBUTTON, NEAR* PTBBUTTON, FAR* LPTBBUTTON;
  2879.  typedef const TBBUTTON FAR* LPCTBBUTTON;
  2880.  
  2881. Submitted by Eric Heimburg.
  2882.  
  2883. ----------------------------------------------------------------------
  2884.  
  2885. WDJ SDK Annotation #132
  2886. TYPE:       Win32
  2887. TOPIC:      EM_POSFROMCHAR
  2888. KEYWORD:    EM_POSFROMCHAR AND "See also"
  2889.  
  2890. The documentation for the wParam, lParam and return value is 
  2891. completely wrong. It should be as follows:
  2892.  
  2893.  wParam - address of point structure to retrieve the coordinates
  2894.  lParam - zero based index of character
  2895.  Return value - not used
  2896.  
  2897. Reference: PSS Q137805
  2898.  
  2899. Submitted by Fred Heidrich.
  2900.  
  2901. ----------------------------------------------------------------------
  2902.  
  2903. WDJ SDK Annotation #133
  2904. TYPE:       Win32
  2905. TOPIC:      EM_CHARFROMPOS
  2906. KEYWORD:    EM_CHARFROMPOS AND "See also"
  2907.  
  2908. The documentation for the lParam and return value is wrong. It 
  2909. should be as follows:
  2910.  
  2911.  wParam - 0 (not used)
  2912.  lParam - Specifies a pointer to a POINT structure that contains the
  2913. coordinates for the character position wanted. 
  2914.  Return value - specifies the character index
  2915.  
  2916. Reference: PSS Q137805
  2917.  
  2918. Submitted by Fred Heidrich.
  2919.  
  2920. ----------------------------------------------------------------------
  2921.  
  2922. WDJ MFC Annotation #134
  2923. TYPE:       MFC 4.0
  2924. TOPIC:      CEdit::PosFromChar
  2925. KEYWORD:    CEdit::PosFromChar AND "See also"
  2926.  
  2927. The MFC wrapper internally calls the EM_POSFROMCHAR function passing
  2928. the documented values. Unfortunately, there is a documentation error in
  2929. EM_POSFROMCHAR, and therefore PosFromChar will not work correctly. 
  2930.  
  2931. Read SDK Annotation #132 or PSS Q137805 for more details.
  2932. This error has been corrected in MFC 4.1
  2933.  
  2934. ----------------------------------------------------------------------
  2935.  
  2936. WDJ MFC Annotation #135
  2937. TYPE:       MFC 4.0
  2938. TOPIC:      CEdit::CharFromPos
  2939. KEYWORD:    CEdit::CharFromPos AND "See also"
  2940.  
  2941. The MFC wrapper internally calls the EM_CHARFROMPOS function passing
  2942. the documented values. Unfortunately, there is a documentation error in
  2943. EM_CHARFROMPOS, and therefore CharFromPos will not work correctly. 
  2944.  
  2945. Read SDK Annotation #133 or PSS Q137805 for more details.
  2946. This error has been corrected in MFC 4.1
  2947.  
  2948. ----------------------------------------------------------------------
  2949.  
  2950. WDJ SDK Annotation #136
  2951. TYPE:       Win32
  2952. TOPIC:      BM_SETIMAGE
  2953. KEYWORD:    BM_SETIMAGE AND "See also"
  2954.  
  2955. The documentation for wParam is incorrect. wParam actually specifies the 
  2956. type of handle passed in lParam. It must be set either IMAGE_BITMAP or
  2957. IMAGE_ICON.
  2958.  
  2959. Also, this message will work only on buttons created with the 
  2960. BS_BITMAP or BS_ICON style.
  2961.  
  2962. Reference: PSS Q125673
  2963.  
  2964. Submitted by Paula Tomlinson.
  2965.  
  2966. ----------------------------------------------------------------------
  2967.  
  2968. WDJ SDK Annotation #137
  2969. TYPE:       Win16
  2970. TOPIC:      GetOpenFileName
  2971. KEYWORD:    GetOpenFileName
  2972.  
  2973. In 16-bit Windows, if you call GetOpenFileName with a string buffer of 10 
  2974. and set nMaxFile to 10, and the user selected a file whose full path name 
  2975. is 10 characters long, Windows appends a NULL character at the 11th byte 
  2976. and returns the filename. This behaviour remains in Win95.
  2977.  
  2978. Therefore, if you set nMaxFile to n, specify a buffer of length n+1 before
  2979. calling this function.
  2980.  
  2981. Reference: March TechNet CD Q137194
  2982.  
  2983. Submitted by: V.Ramachandran.
  2984.  
  2985.  
  2986. ----------------------------------------------------------------------
  2987.  
  2988. WDJ SDK Annotation #137
  2989. TYPE:       Win32
  2990. TOPIC:      GetOpenFileName
  2991. KEYWORD:    GetOpenFileName AND "See also"
  2992.  
  2993. In 16-bit Windows, if you call GetOpenFileName with a string buffer of 10 
  2994. and set nMaxFile to 10, and the user selected a file whose full path name 
  2995. is 10 characters long, Windows appends a NULL character at the 11th byte 
  2996. and returns the filename. This behaviour remains in Win95.
  2997.  
  2998. Therefore, if you set nMaxFile to n, specify a buffer of length n+1 before
  2999. calling this function.
  3000.  
  3001. Reference: March TechNet CD Q137194
  3002.  
  3003. Submitted by: V.Ramachandran.
  3004.  
  3005. ----------------------------------------------------------------------
  3006.  
  3007. WDJ SDK Annotation #138
  3008. TYPE:       Win32
  3009. TOPIC:      LB_DIR
  3010. KEYWORD:    LB_DIR AND "See also"
  3011.  
  3012. Sending a LB_DIR message to a listbox that specifies a long filename in 
  3013. the lParam returns LB_ERR in Windows 95, but works fine under Windows 
  3014. NT 3.51
  3015.  
  3016. In order to work around this bug, call GetShortPathName on the long
  3017. filename and pass the short filename to LB_DIR.
  3018.  
  3019. Reference: March TechNet CD Q131286
  3020.  
  3021. Submitted by: V.Ramachandran.
  3022.  
  3023. ----------------------------------------------------------------------
  3024.  
  3025. WDJ SDK Annotation #139
  3026. TYPE:       Win16
  3027. TOPIC:      EM_SETSEL
  3028. KEYWORD:    EM_SETSEL
  3029.  
  3030. The SDK documentation mentions that if wParam is 0, the caret is scrolled
  3031. into view, and if wParam is 1 it is not scrolled into view. However,
  3032. this parameter is not used for single line edit controls. 
  3033.  
  3034. Also, the order of the start and end positions specified in the lParam 
  3035. is not respected by single line edit controls.
  3036.  
  3037. Both wParam and lParam work as documented for multiline edit controls.
  3038.  
  3039. Reference: MSDN PSS Q102641, Q64758.
  3040.  
  3041. Submitted by: V.Ramachandran.
  3042.  
  3043. ----------------------------------------------------------------------
  3044.  
  3045. WDJ SDK Annotation #140
  3046. TYPE:       Win32
  3047. TOPIC:      STGM
  3048. KEYWORD:    STGM AND "See also"
  3049.  
  3050. The documentation fails to mention that for all storage and stream 
  3051. creation functions, you HAVE to specify a share mode flag. For example, 
  3052. a call to StgCreateDocfile with STGM_CREATE | STGM_READWRITE will fail;
  3053. while passing STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE will 
  3054. work correctly.
  3055.  
  3056. Submitted by: V.Ramachandran.
  3057.  
  3058.  
  3059.  
  3060. -------------------------------------------------------------------------
  3061.  
  3062. WDJ SDK Annotation #141
  3063. TYPE:       Win32
  3064. TOPIC:      WM_SETICON
  3065. KEYWORD:    WM_SETICON AND "See also"
  3066.  
  3067. Contrary to what the documentation says, Windows uses the small icon in
  3068. the window caption (including the caption of the minimized window). 
  3069. Windows uses the large icon when you press Alt+Tab to switch to another
  3070. application. 
  3071.  
  3072. ----------------------------------------------------------------------
  3073.  
  3074. WDJ SDK Annotation #142
  3075. TYPE:       Win16
  3076. TOPIC:      JournalRecordProc
  3077. KEYWORD:    JournalRecordProc
  3078.  
  3079. lParam is incorrectly documented -- it actually points to a 
  3080. EVENTMSG structure.
  3081.  
  3082. ----------------------------------------------------------------------
  3083.  
  3084. WDJ SDK Annotation #143
  3085. TYPE:       Win32
  3086. TOPIC:      GetDeviceCaps
  3087. KEYWORD:    GetDeviceCaps AND "See also"
  3088.  
  3089. The documentation fails to mention 2 additional values for the 
  3090. index parameter:
  3091.  
  3092.  SCALINGFACTORX - Scaling factor for the x-axis of a printer
  3093.  SCALINGFACTORY - Scaling factor for the y-axis of a printer
  3094.  
  3095. Also, GetDeviceCaps provides the following 6 indices in place of 
  3096. printer Escapes:
  3097.  
  3098.    Index for GetDeviceCaps   Printer Escape Replaced
  3099.    --------------------------------------------------------
  3100.    PHYSICALWIDTH             GETPHYSPAGESIZE
  3101.    PHYSICALHEIGHT            GETPHYSPAGESIZE
  3102.    PHYSICALOFFSETX           GETPRINTINGOFFSET
  3103.    PHYSICALOFFSETY           GETPRINTINGOFFSET
  3104.    SCALINGFACTORX            GETSCALINGFACTOR
  3105.    SCALINGFACTORY            GETSCALINGFACTOR
  3106.  
  3107. Reference: MSDN Knowledge Base PSS Q125692
  3108.  
  3109. Submitted by Sudhir Menon.
  3110.  
  3111. ----------------------------------------------------------------------
  3112.  
  3113. WDJ SDK Annotation #144
  3114. TYPE:       Win32
  3115. TOPIC:      MessageBoxIndirect
  3116. KEYWORD:    MessageBoxIndirect AND "See also"
  3117.  
  3118. The documentation incorrectly mentions that this function returns a 
  3119. BOOL value, and gives no description of it. In fact, the return value 
  3120. is an int, and it has the same meaning as the return value for MessageBox.
  3121.  
  3122. Submitted by Phil Rodgers.
  3123.  
  3124. ----------------------------------------------------------------------
  3125.  
  3126. WDJ SDK Annotation #145
  3127. TYPE:       Win32
  3128. TOPIC:      LVM_EDITLABEL
  3129. KEYWORD:    LVM_EDITLABEL AND "See also"
  3130.  
  3131. Note that the listview control allows label editing
  3132. by creating a child edit control with an ID of IDOK.
  3133. That edit control will send notifications to the parent
  3134. of the listview control (e.g., your dialog box), so
  3135. if you have an "OK" button with the same ID, do not
  3136. write code like this:
  3137.  
  3138.  if(Command == IDOK)
  3139.      EndDialog(Dialog, TRUE);
  3140.  
  3141. since the first time the user edits a label, the dialog
  3142. will immediately disappear as though the user pressed
  3143. the "OK" button. Instead, use code like this:
  3144.  
  3145.  if(Command == IDOK && Code == BN_CLICKED)
  3146.      EndDialog(Dialog, TRUE);
  3147.  
  3148. ----------------------------------------------------------------------
  3149.  
  3150. WDJ SDK Annotation #146
  3151. TYPE:       Win32
  3152. TOPIC:      TVN_ENDLABELEDIT
  3153. KEYWORD:    TVN_ENDLABELEDIT AND "See also"
  3154.  
  3155. When editing labels in a TreeView control which is part of a dialog, 
  3156. this notification is sent only if the user ends label editing using 
  3157. the mouse (by clicking outside the edit control). Using the Enter and 
  3158. Return keys do not work because the edit control does not handle the
  3159. WM_GETDLGCODE correctly, and therefore IsDialogMessage processes these
  3160. keys.
  3161.  
  3162. In order to make the TreeView control accept the changes when the user
  3163. presses Enter, and reject the changes on Escape, do the following:
  3164.  
  3165. 1. In the TVN_BEGINLABELEDIT notification, get the edit contol handle 
  3166. using TVM_GETEDITCONTROL. Subclass the edit control.
  3167.  
  3168. 2. In the subclassed procedure, handle the WM_GETDLGCODE message and
  3169. return WM_WANTALLKEYS. 
  3170.  
  3171. 3. Handle the WM_CHAR message. When wParam is VK_ESCAPE, send a
  3172. TVM_ENDLABELEDITNOW message to the edit control with fCancel = TRUE. 
  3173. When wParam is VK_RETURN, send TVM_ENDLABELEDITNOW with 
  3174. fCancel = FALSE. All other WM_CHAR messages should be passed to the
  3175. default edit control procedure.
  3176.  
  3177. 4. In the TVN_ENDLABELEDIT notification, remove the subclassing.
  3178.  
  3179. Reference: MSDN article PSS Q130691
  3180.  
  3181. ----------------------------------------------------------------------
  3182.  
  3183. WDJ SDK Annotation #147
  3184. TYPE:       Win16
  3185. TOPIC:      GetWindowTextLength
  3186. KEYWORD:    GetWindowTextLength
  3187.  
  3188. In Windows 3.1, calling GetWindowTextLength on a drop list 
  3189. combo box (CBS_DROPDOWNLIST) incorrectly returns -1. 
  3190.  
  3191. However in Win32 (for both 16 and 32 bit applications),
  3192. GetWindowTextLength returns the length of the string in the static 
  3193. portion of the combo box.
  3194.  
  3195. Submitted by Sinisa Djurekovic.
  3196.  
  3197. ----------------------------------------------------------------------
  3198.  
  3199.  
  3200. WDJ SDK Annotation #147
  3201. TYPE:       Win32
  3202. TOPIC:      GetWindowTextLength
  3203. KEYWORD:    GetWindowTextLength AND "See also"
  3204.  
  3205. In Windows 3.1, calling GetWindowTextLength on a drop list 
  3206. combo box (CBS_DROPDOWNLIST) incorrectly returns -1. 
  3207.  
  3208. However in Win32 (for both 16 and 32 bit applications),
  3209. GetWindowTextLength returns the length of the string in the static 
  3210. portion of the combo box.
  3211.  
  3212. Submitted by Sinisa Djurekovic.
  3213.  
  3214. ----------------------------------------------------------------------
  3215.  
  3216. WDJ MFC Annotation #147
  3217. TYPE:       MFC 1.x, 2.x
  3218. TOPIC:      CWnd::GetWindowText
  3219. KEYWORD:    CWnd::GetWindowText AND CString AND Parameters
  3220.  
  3221. If you call GetWindowText (CString&) on a CWnd object which specifies a 
  3222. Combo box with the CBS_DROPDOWNLIST style, you will get an assertion
  3223. in strcore.cpp.
  3224.  
  3225. This is because GetWindowText internally calls GetWindowTextLength. 
  3226. Calling GetWindowTextLength on a drop list combo box (CBS_DROPDOWNLIST)
  3227. incorrectly returns -1, and MFC asserts because -1 is an invalid length
  3228. for a CString object.
  3229.  
  3230. Submitted by Sinisa Djurekovic.
  3231.  
  3232. ----------------------------------------------------------------------
  3233.  
  3234. WDJ SDK Annotation #148
  3235. TYPE:       Win32
  3236. TOPIC:      FindFirstFile
  3237. KEYWORD:    FindFirstFile AND "See also"
  3238.  
  3239. In Windows 95, the FindFirstFile() function interprets a wildcard (?) as
  3240. "any character" instead of "zero or one character," as you would expect. 
  3241. For example, if the files, TEMP.TXT and TEMPTEMP.TXT, are in the same
  3242. directory, using FindFirstFile ("TEM?????.???", &findData) finds the 
  3243. TEMPTEMP.TXT file, but not the TEMP.TXT file:
  3244.  
  3245. This function works correctly under Windows NT.
  3246.  
  3247. Reference: MSDN PSS ID No. Q130860
  3248.  
  3249. ----------------------------------------------------------------------
  3250.  
  3251. WDJ SDK Annotation #149
  3252. TYPE:       Win32
  3253. TOPIC:      CreateDirectoryEx
  3254. KEYWORD:    CreateDirectoryEx AND "See also"
  3255.  
  3256. When you specify a template directory string with two back slashes (\\)
  3257. at the end of the string, CreateDirectoryEx returns FALSE indicating
  3258. error, even though the API successfully created the new directory.
  3259. GetLastError returns ERROR_INVALID_PARAMETER (87L).
  3260.  
  3261. Under Windows 95, passing "c:\\" as the template directory (first 
  3262. parameter) to CreateDirectoryEx will return FALSE, even if it 
  3263. successfully created the new directory.
  3264.  
  3265. The function works correctly under Windows NT.
  3266.  
  3267. Reference: MSDN PSS ID No. Q140455
  3268.  
  3269. ----------------------------------------------------------------------
  3270.  
  3271. WDJ MFC Annotation #150
  3272. TYPE:       MFC 
  3273. TOPIC:      CStatusBar::SetPaneText
  3274. KEYWORD:    CStatusBar::SetPaneText AND "See also"
  3275.  
  3276. Just calling CStatusBar::SetPaneText will not display the text in the
  3277. status bar pane. You need to add a UI update handler for the pane for the
  3278. text to appear correctly.
  3279.  
  3280. In order to set the text for pane index 4, and id ID_PANE_FOUR do:
  3281.  SetPaneText (4, "Some text", TRUE);
  3282. and a UI handler in the message map as follows:
  3283.  ON_UPDATE_COMMAND_UI (ID_PANE_FOUR, OnUpdatePane)
  3284. and in the appropriate .cpp file add:
  3285.  void CMyClass::OnUpdatePane (CCmdUI *pCmdUI)
  3286.  {
  3287.     pCmdUI->Enable ();
  3288.  }
  3289.  
  3290. Reference: MSDN PSS No. Q109039
  3291.  
  3292.  
  3293. ----------------------------------------------------------------------
  3294.  
  3295.  
  3296. WDJ MFC Annotation #151
  3297. TYPE:       MFC 2.x
  3298. TOPIC:      CRecordSet::Open
  3299. KEYWORD:    CRecordSet::Open
  3300.  
  3301. The documentation says that, for the param dwOptions, an enum 
  3302. "CRecordset::defaultOptions" can be specified, which will make the
  3303. recordset updatable. However, this enum is not defined. Use
  3304. "CRecordset::none" instead.
  3305.  
  3306. Submitted by Nagendra R.
  3307.  
  3308. ----------------------------------------------------------------------
  3309.  
  3310. WDJ SDK Annotation #152
  3311. TYPE:       Win16
  3312. TOPIC:      EnumFontFamProc
  3313. KEYWORD:    EnumFontFamProc
  3314.  
  3315. The SDK documentation incorrectly mentions that the first parameter
  3316. lpnlf points to a NEWLOGFONT structure, which is not defined at all. 
  3317. lpnlf actually points to a ENUMLOGFONT structure.
  3318.  
  3319. Reference: MSDN KB Q87975
  3320.  
  3321. Submitted by V.Ramachandran.
  3322.  
  3323. ----------------------------------------------------------------------
  3324.  
  3325. WDJ SDK Annotation #153
  3326. TYPE:       Win32
  3327. TOPIC:      WM_CANCELMODE
  3328. KEYWORD:    WM_CANCELMODE AND "See also"
  3329.  
  3330. The WM_CANCELMODE gets sent to the active window before another dialog or
  3331. message box is displayed. It is not sent to the focus window as the
  3332. documentation claims.
  3333.  
  3334. Therefore if a OK Button in Dialog 1 displays Dialog 2, Dialog 1 gets a
  3335. WM_CANCELMODE message and not the OK button, which should have been the 
  3336. case as per the documentation.
  3337.  
  3338. Submitted by V.Ramachandran.
  3339.  
  3340. ----------------------------------------------------------------------
  3341.  
  3342. WDJ SDK Annotation #154
  3343. TYPE:       Win32
  3344. TOPIC:      CreateWindow
  3345. KEYWORD:    CreateWindow AND "See also"
  3346.  
  3347. The documentation does not mention that static controls created with the
  3348. SS_SIMPLE style do not gray their text when they are disabled unlike
  3349. static controls without the SS_SIMPLE style.
  3350.  
  3351. Submitted by Nagendra R.
  3352.  
  3353. ----------------------------------------------------------------------
  3354.  
  3355. WDJ MFC Annotation #155
  3356. TYPE:       MFC 4.x
  3357. TOPIC:      CFileDialog::GetNextPathName
  3358. KEYWORD:    CFileDialog::GetNextPathName
  3359.  
  3360. If you select multiple files in a root drive, GetNextPathName returns
  3361. strings with two back slashes '\' after the drive letter. For example, if
  3362. you select the autoexec.bat and config.sys files from C:\ using a multiple
  3363. selection file open dialog, GetNextPathName will return the strings:
  3364. "c:\\autoexec.bat" and "c:\\config.sys". This problem does not appear when
  3365. you select only one file.
  3366.  
  3367. A workaround would be to check the strings returned by GetNextPathName for
  3368. double back slashes, and remove them yourself.
  3369.  
  3370.  CString sFile = dlg.GetNextPathName (pos);
  3371.  #if _MFC_VER >= 0x0400
  3372.  if ((sFile [1] == ':') && (sFile [2] == '\\') && (sFile [3] == '\\')) {
  3373.     sFile = sFile.Left (3) + sFile.Right (sFile.GetLength () - 4);
  3374.  }
  3375.  #endif // end of MFC 4.x hack!
  3376.  
  3377. Submitted by David Lowndes.
  3378.  
  3379. ----------------------------------------------------------------------
  3380.  
  3381. WDJ MFC Annotation #156
  3382. TYPE:       MFC 4.x
  3383. TOPIC:      CToolTipCtrl::GetToolInfo
  3384. KEYWORD:    CToolTipCtrl::GetToolInfo
  3385.  
  3386. The documentation incorrectly states that the first parameter should be 
  3387. of type LPTOOLINFO. The function actually accepts a CToolInfo& (reference
  3388. to a undocumented CToolInfo class). If the call succeeds, the szText 
  3389. parameter of the CToolInfo variable contains the tooltip text. 
  3390.  
  3391. Submitted by Paul Stemper.
  3392.  
  3393. ----------------------------------------------------------------------
  3394.  
  3395. WDJ MFC Annotation #157
  3396. TYPE:       MFC 4.x
  3397. TOPIC:      CToolTipCtrl::AddTool
  3398. KEYWORD:    CToolTipCtrl::AddTool
  3399.  
  3400. The documentation fails to mention that you cannot set a tooltip to a
  3401. static control using the AddTool function.
  3402.  
  3403. Submitted by Sudhir Menon.
  3404.  
  3405. ----------------------------------------------------------------------
  3406.  
  3407. WDJ MFC Annotation #158
  3408. TYPE:       MFC 4.x
  3409. TOPIC:      CTreeCtrl::GetNextVisibleItem
  3410. KEYWORD:    CTreeCtrl::GetNextVisibleItem
  3411.  
  3412. GetNextVisibleItem and GetPrevVisibleItem return the next
  3413. or previous item, not the next or previous visible item.
  3414.  
  3415. Submitted by Mark Gorokhov.
  3416.  
  3417. ----------------------------------------------------------------------
  3418.  
  3419. WDJ MFC Annotation #158
  3420. TYPE:       MFC 4.x
  3421. TOPIC:      CTreeCtrl::GetPrevVisibleItem
  3422. KEYWORD:    CTreeCtrl::GetPrevVisibleItem
  3423.  
  3424. GetNextVisibleItem and GetPrevVisibleItem return the next
  3425. or previous item, not the next or previous visible item.
  3426.  
  3427. Submitted by Mark Gorokhov.
  3428.  
  3429. ----------------------------------------------------------------------
  3430.  
  3431. WDJ MFC Annotation #159
  3432. TYPE:       MFC 4.x
  3433. TOPIC:      CFontDialog::GetCurrentFont
  3434. KEYWORD:    CFontDialog::GetCurrentFont
  3435.  
  3436. Though the documentation mentions that you can call this function after
  3437. calling DoModal, the function incorrectly ASSERTS that its window handle 
  3438. is not NULL.
  3439.  
  3440. Instead, use the public CFontDialog member variable m_lf.
  3441.  
  3442. Submitted by Tim Lesher.
  3443.  
  3444. ----------------------------------------------------------------------
  3445.  
  3446. WDJ SDK Annotation #160
  3447. TYPE:       Win32
  3448. TOPIC:      WM_MOVE
  3449. KEYWORD:    WM_MOVE AND "See also"
  3450.  
  3451. The SDK documentation tells you to use the following two lines to calculate
  3452. the x, and y positions of the window after it has been moved.
  3453.  
  3454.  xPos = (int) LOWORD(lParam);    // horizontal position
  3455.  yPos = (int) HIWORD(lParam);    // vertical position
  3456.  
  3457. Though this worked fine in 16-bit Windows, it will fail for negative
  3458. coordinates in 32-bit Windows. Instead use the following two lines to
  3459. calculate the coordinates:
  3460.  
  3461.  xPos = (int) (short)LOWORD(lParam);    // horizontal position
  3462.  yPos = (int)(short) HIWORD(lParam);    // vertical position
  3463.  
  3464. Submitted by Steven M. Kinney.
  3465.  
  3466. ----------------------------------------------------------------------
  3467.  
  3468. WDJ MFC Annotation #161
  3469. TYPE:       MFC 4.x
  3470. TOPIC:      CWnd::OnMove
  3471. KEYWORD:    CWnd::OnMove AND Parameters NOT LPRECT
  3472.  
  3473. MFC supplies LOWORD (lParam) and HIWORD (lParam) of the WM_MOVE message 
  3474. for the x, and y parameters of this function, respectively. Since x and y
  3475. are defined as integers, you will get very large numbers for negative
  3476. coordinates.
  3477.  
  3478. Whenever you want to handle the WM_MOVE message, do the following:
  3479. 1. Define a message handler: ON_MESSAGE (WM_MOVE, OnMyMove) in the message
  3480.    map.
  3481. 2. Write the OnMyMove function as follows:
  3482.     LRESULT ClassName::OnMyMove (WPARAM, LPARAM lParam)
  3483.     {
  3484.         x = (int) (short)LOWORD(lParam);    // horizontal position
  3485.         y = (int)(short) HIWORD(lParam);    // vertical position
  3486.  
  3487.         // Do your processing here ...
  3488.  
  3489.         return Default ();
  3490.     }
  3491.  
  3492. Submitted by Steven M. Kinney.
  3493.  
  3494. ----------------------------------------------------------------------
  3495.  
  3496. WDJ MFC Annotation #162
  3497. TYPE:       MFC 2.x
  3498. TOPIC:      CRecordset::Delete
  3499. KEYWORD:    CRecordset::Delete AND Remarks NOT Symptoms
  3500.  
  3501. This function is incorrectly documented as returning BOOL. It actually
  3502. returns void.
  3503.  
  3504. This documentation error has been corrected in MFC 4.x
  3505.  
  3506. Submitted by Tushar Bhatia.
  3507.  
  3508.  
  3509. ----------------------------------------------------------------------
  3510.  
  3511.  
  3512. WDJ SDK Annotation #163
  3513. TYPE:       Win32
  3514. TOPIC:      EM_GETLINE
  3515. KEYWORD:    EM_GETLINE AND "See also"
  3516.  
  3517. When using this message under Win32s (1.30a and above) with
  3518. the RichEdit control, the parameters the message takes are:
  3519.  
  3520.     wParam = 0;
  3521.     lParam = &em32s;
  3522.  
  3523. Where em32s is a structure defined as:
  3524.  
  3525.     struct EM32S {
  3526.         DWORD wParam;
  3527.         DWORD lParam;
  3528.         };
  3529.  
  3530. The documented wParam and lParam values are stored in the
  3531. EM32S structure. 
  3532.  
  3533. Submitted by Larry Widing.
  3534.  
  3535. ----------------------------------------------------------------------
  3536.  
  3537. WDJ SDK Annotation #163
  3538. TYPE:       Win32
  3539. TOPIC:      EM_LINEINDEX
  3540. KEYWORD:    EM_LINEINDEX AND "See also"
  3541.  
  3542. When using this message under Win32s (1.30a and above) with
  3543. the RichEdit control, the parameters the message takes are:
  3544.  
  3545.     wParam = 0;
  3546.     lParam = &em32s;
  3547.  
  3548. Where em32s is a structure defined as:
  3549.  
  3550.     struct EM32S {
  3551.         DWORD wParam;
  3552.         DWORD lParam;
  3553.         };
  3554.  
  3555. The documented wParam and lParam values are stored in the
  3556. EM32S structure. 
  3557.  
  3558. Submitted by Larry Widing.
  3559.  
  3560. ----------------------------------------------------------------------
  3561.  
  3562. WDJ SDK Annotation #163
  3563. TYPE:       Win32
  3564. TOPIC:      EM_LINELENGTH
  3565. KEYWORD:    EM_LINELENGTH AND "See also"
  3566.  
  3567. When using this message under Win32s (1.30a and above) with
  3568. the RichEdit control, the parameters the message takes are:
  3569.  
  3570.     wParam = 0;
  3571.     lParam = &em32s;
  3572.  
  3573. Where em32s is a structure defined as:
  3574.  
  3575.     struct EM32S {
  3576.         DWORD wParam;
  3577.         DWORD lParam;
  3578.         };
  3579.  
  3580. The documented wParam and lParam values are stored in the
  3581. EM32S structure. 
  3582.  
  3583. Submitted by Larry Widing.
  3584.  
  3585. ----------------------------------------------------------------------
  3586.  
  3587. WDJ SDK Annotation #163
  3588. TYPE:       Win32
  3589. TOPIC:      EM_LINESCROLL
  3590. KEYWORD:    EM_LINESCROLL AND "See also"
  3591.  
  3592. When using this message under Win32s (1.30a and above) with the RichEdit 
  3593. control, the parameters the message takes are:
  3594.  
  3595.     wParam = 0;
  3596.     lParam = &em32s;
  3597.  
  3598. Where em32s is a structure defined as:
  3599.  
  3600.     struct EM32S {
  3601.         DWORD wParam;
  3602.         DWORD lParam;
  3603.         };
  3604.  
  3605. The documented wParam and lParam values are stored in the EM32S structure.
  3606.  
  3607. Submitted by Larry Widing.
  3608.  
  3609. ----------------------------------------------------------------------
  3610.  
  3611. WDJ SDK Annotation #164
  3612. TYPE:       Win32
  3613. TOPIC:      EDITSTREAM
  3614. KEYWORD:    EDITSTREAM AND "See also"
  3615.  
  3616. The return value from this function is incorrectly
  3617. documented.  The return value from the EditStreamCallback is
  3618. interpreted as an SCODE - you should return 0 to indicate
  3619. success or an error code otherwise (both while reading and
  3620. writing). 
  3621.  
  3622. Reference: MSDN KB article Q136810
  3623.  
  3624. Submitted by Donald Munro. 
  3625.  
  3626. ----------------------------------------------------------------------
  3627.  
  3628. WDJ SDK Annotation #165
  3629. TYPE:       Win16
  3630. TOPIC:      GetNextDlgGroupItem
  3631. KEYWORD:    GetNextDlgGroupItem
  3632.  
  3633. The Win16 SDK fails to mention that this function ignores
  3634. controls that are part of the group but are disabled.  The
  3635. documentation has been corrected in Win32. 
  3636.  
  3637. If you use MFC, check out Annotation #166 (DDX_Radio) for
  3638. this bug's repercussions. 
  3639.  
  3640. ----------------------------------------------------------------------
  3641.  
  3642. WDJ MFC Annotation #166
  3643. TYPE:       MFC
  3644. TOPIC:      DDX_Radio
  3645. KEYWORD:    DDX_Radio
  3646.  
  3647. DDX_Radio internally uses GetNextDlgGroupItem (see SDK
  3648. annotation #165) and therefore ignores disabled
  3649. radio-buttons.  This could causes 2 radio buttons in the
  3650. same group to be selected, if a disabled radio-button is
  3651. selected.  Generally, you are better off not using this
  3652. function if you are going to enable/disable radio-buttons. 
  3653. Use the Windows SDK functions instead.  This applies to MFC
  3654. 1.x and 2.x. 
  3655.  
  3656. Reference: MSDN KB Q114980
  3657.  
  3658. ----------------------------------------------------------------------
  3659.  
  3660. WDJ SDK Annotation #167
  3661. TYPE:       Win32
  3662. TOPIC:      CreatePen
  3663. KEYWORD:    CreatePen AND "See also"
  3664.  
  3665. If you specify a width greater than 1 for one of the the
  3666. following styles - PS_DASH, PS_DOT, PS_DASHDOT,
  3667. PS_DASHDOTDOT, CreatePen returns a pen with the specified
  3668. width but with the PS_SOLID style. 
  3669.  
  3670. Submitted by Muthuvale Shanmugam.
  3671.  
  3672. ----------------------------------------------------------------------
  3673.  
  3674. WDJ SDK Annotation #168
  3675. TYPE:       Win32
  3676. TOPIC:      WindowFromPoint
  3677. KEYWORD:    WindowFromPoint AND "See also"
  3678.  
  3679. If given a point over a static text control, WindowFromPoint()
  3680. returns the handle of the window "under" the static text control.
  3681.  
  3682. Submitted by Muthuvale Shanmugam.
  3683.  
  3684. ----------------------------------------------------------------------
  3685.  
  3686. WDJ SDK Annotation #169
  3687. TYPE:       Win32
  3688. TOPIC:      TranslateMessage
  3689. KEYWORD:    TranslateMessage AND "See also"
  3690.  
  3691. Though the documentation mentions that it returns TRUE only
  3692. if it translates message, it actually returns TRUE for all
  3693. WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN and WM_SYSKEYUP
  3694. messages.  This behaviour is consistent with Windows 3.1
  3695.  
  3696. Reference: MSDN KB Q137231
  3697.  
  3698.  
  3699.  
  3700. ----------------------------------------------------------------------
  3701.  
  3702. WDJ SDK Annotation #170
  3703. TYPE:       Win32
  3704. TOPIC:      LoadLibrary
  3705. KEYWORD:    LoadLibrary AND "See also"
  3706.  
  3707. When writing code for a Win32 DLL, you may be tempted to
  3708. use declare thread-local variables using Windows-specific
  3709. keywords like this:
  3710.  
  3711.   __declspec(thread) int  ThisThreadStatus;
  3712.  
  3713. If you do, however, then the resulting DLL can only be
  3714. loaded implicitly (by linking with an import library).
  3715. If any program tries to use LoadLibrary() or LoadLibraryEx()
  3716. to load such a DLL, the call will fail and GetLastError()
  3717. will report a code of 1114L (DLL initialization failed),
  3718. even though your DLL's entry point never gets called.
  3719.  
  3720. The only work around is to simply not use __declspec(thread)
  3721. in your DLL. Either use the TlsXxxx() functions to allocate
  3722. thread-local storage, or use your own algorithm for associating
  3723. data with thread handles.
  3724.  
  3725.  
  3726. ----------------------------------------------------------------------
  3727.  
  3728.  
  3729. WDJ SDK Annotation #171
  3730. TYPE:       Win32
  3731. TOPIC:      GetLastError
  3732. KEYWORD:    GetLastError AND "See also" NOT MAPIERROR
  3733.  
  3734. Some versions of the documentation for GetLastError() state
  3735. that a listing of the error codes is found in WINNT.H.  The
  3736. list of error codes is actually found in the file
  3737. WINERROR.H. 
  3738.  
  3739. Submitted by Katy Mulvey.
  3740.  
  3741.  
  3742. ----------------------------------------------------------------------
  3743.  
  3744.  
  3745. WDJ SDK Annotation #172
  3746. TYPE:       Win32
  3747. TOPIC:      WaitForMultipleObjects
  3748. KEYWORD:    WaitForMultipleObjects AND "See also"
  3749.  
  3750. The Windows 95 implementation of this function
  3751. has a bug (see the reference for a complete
  3752. explanation). If the same thread claims a mutex
  3753. more than once, then a second thread calls
  3754. WaitForMultipleObjects() to wait on that mutex and at
  3755. least one other object, WaitForMultipleObjects() will
  3756. incorrectly consider the mutex free when the other
  3757. objects being waited on become signaled.
  3758.  
  3759. Reference: p. 44, December 1996 Windows Developer's Journal
  3760.  
  3761.  
  3762.  
  3763.  
  3764. ----------------------------------------------------------------------
  3765.  
  3766.  
  3767. WDJ SDK Annotation #173
  3768. TYPE:       Win32
  3769. TOPIC:      TBBUTTON
  3770. KEYWORD:    TBBUTTON AND "See also"
  3771.  
  3772. The documentation incorrectly claims that for
  3773. separators (fsStyle equal to TBSTYLE_SEP), the
  3774. idCommand field must be zero. In fact, you can
  3775. assign toolbar separators a non-zero ID. In fact,
  3776. it is important to assign unique IDs to separators
  3777. if they have non-default widths so the customization
  3778. features will work properly. Also, it's a common
  3779. technique to use a "fat" separator as a placeholder
  3780. for a control (such as a drop-down listbox) that you
  3781. want to appear on the toolbox. You will need to
  3782. assign such separators a non-zero ID so that you
  3783. can locate the correct position for the control.
  3784.  
  3785.  
  3786. Reference: p. 45, November 1996 Windows Developer's Journal
  3787.  
  3788.  
  3789.  
  3790.  
  3791. ----------------------------------------------------------------------
  3792.  
  3793.  
  3794.  
  3795.  
  3796. WDJ SDK Annotation #174
  3797. TYPE:       Win32
  3798. TOPIC:      WM_GETDLGCODE
  3799. KEYWORD:    WM_GETDLGCODE AND "See also"
  3800.  
  3801.  
  3802. If a 32-bit control returns DLGC_HASSETSEL, Windows 95 will not send a
  3803. EM_SETSEL message when the control gets the focus.  Instead, Windows 95
  3804. sends the control a message with the same value as the 16-bit EM_SETSEL
  3805. (0x401) with 16-bit style parameters.  Under Windows NT, your control
  3806. will get the normal 32-bit EM_SETSEL message. 
  3807.  
  3808. Note: Under Win32, the EM_ messages start at 0xB0 and not at WM_USER
  3809. (0x400) as they did in Win16.
  3810.  
  3811. Submitted by Robert Mashlan.
  3812.  
  3813.  
  3814. ------------------------------------------------------------------------
  3815.  
  3816.  
  3817. WDJ SDK Annotation #175
  3818. TYPE:       Win32
  3819. TOPIC:      GetRegionData
  3820. KEYWORD:    GetRegionData AND "See also"
  3821.  
  3822. The documentation for the return value is incorrect.  If the
  3823. function succeeds and dwCount specifies an adequate number
  3824. of bytes, the return value is always dwCount.  If the
  3825. function fails or if dwCount specifies less than adequate
  3826. number of bytes, the return value is 0. 
  3827.  
  3828. Submitted by Peter C. Jahans.
  3829.  
  3830. ----------------------------------------------------------------------
  3831.  
  3832. WDJ MFC Annotation #175
  3833. TYPE:       MFC
  3834. TOPIC:      CRgn::GetRegionData
  3835. KEYWORD:    CRgn::GetRegionData
  3836.  
  3837. The documentation for the return value is incorrect.  If the
  3838. function succeeds and dwCount specifies an adequate number
  3839. of bytes, the return value is always dwCount.  If the
  3840. function fails or if dwCount specifies less than adequate
  3841. number of bytes, the return value is 0 (ERROR). 
  3842.  
  3843. Submitted by Peter C. Jahans.
  3844.  
  3845. ----------------------------------------------------------------------
  3846.  
  3847. WDJ SDK Annotation #176
  3848. TYPE:       Win32
  3849. TOPIC:      DrawFocusRect
  3850. KEYWORD:    DrawFocusRect AND "See also"
  3851.  
  3852. DrawFocusRect() works only in MM_TEXT mode.  In other
  3853. modes, this function does not draw the focus rectangle
  3854. correctly, but it does NOT return error values!
  3855.  
  3856. Submitted by Jon-David Wiesman.
  3857.  
  3858. ----------------------------------------------------------------------
  3859.  
  3860. WDJ MFC Annotation #176
  3861. TYPE:       MFC
  3862. TOPIC:      CDC::DrawFocusRect
  3863. KEYWORD:    CDC::DrawFocusRect
  3864.  
  3865. CDC::DrawFocusRect() works only in MM_TEXT mode.  In other
  3866. modes, this function does not draw the focus rectangle
  3867. correctly, but it does NOT return error values!
  3868.  
  3869. Submitted by Jon-David Wiesman.
  3870.  
  3871. ----------------------------------------------------------------------
  3872.  
  3873. WDJ SDK Annotation #177
  3874. TYPE:       Win32
  3875. TOPIC:      FSCTL_DISMOUNT_VOLUME
  3876. KEYWORD:    FSCTL_DISMOUNT_VOLUME AND "See also"
  3877.  
  3878. The SDK documentation for this function mentions "If the
  3879. specified volume is locked, the operation fails." This is
  3880. incorrect.  It should actually read "If the specified volume
  3881. is locked by another process, the operation fails." You must
  3882. do an FSCTL_LOCK_VOLUME before you can do an
  3883. FSCTL_DISMOUNT_VOLUME.
  3884.  
  3885. Also, in the sequence of events for reformatting FAT to NTFS
  3886. as described in the same article, steps 4 and 5 must be
  3887. switched - you need to dismount the volume before you unlock
  3888. the volume. 
  3889.  
  3890. Submitted by Jeffrey S. Goldner.
  3891.  
  3892. ----------------------------------------------------------------------
  3893.  
  3894. WDJ SDK Annotation #178
  3895. TYPE:       Win32
  3896. TOPIC:      CreateProcess
  3897. KEYWORD:    CreateProcess AND "See also"
  3898.  
  3899. If you call CreateProcess() with a dwCreationFlags value
  3900. which includes DEBUG_PROCESS, the call will fail under Win95
  3901. when the debugee is a 16-bit app. 
  3902.  
  3903. Submitted by Marc Cousineau.
  3904.  
  3905. ----------------------------------------------------------------------
  3906.  
  3907. WDJ SDK Annotation #179
  3908. TYPE:       Win32
  3909. TOPIC:      WM_ACTIVATE
  3910. KEYWORD:    WM_ACTIVATE AND "See also"
  3911.  
  3912. The documentation states that the message is sent first to
  3913. the top-level window being deactivated and then to the
  3914. window being activated.  This is incorrect in Win32.  In
  3915. Win32, activation is asynchronous - the activating
  3916. application becomes active immediately and the messages to
  3917. the deactivating application occur later. 
  3918.  
  3919. Reference: MSDN KB Article Q135785
  3920.  
  3921. Submitted by V.Ramachandran.
  3922.  
  3923. ----------------------------------------------------------------------
  3924.  
  3925. WDJ MFC Annotation #179
  3926. TYPE:       MFC
  3927. TOPIC:      CWnd::OnActivate
  3928. KEYWORD:    CWnd::OnActivate
  3929.  
  3930. The documentation states that first OnActivate() is called
  3931. for the main window being deactivated, and then for the main
  3932. window being activated This is incorrect in Win32.  In
  3933. Win32, activation is asynchronous - the activating
  3934. application becomes immediately and the messages to the
  3935. deactivating application occur later. 
  3936.  
  3937. Reference: MSDN KB Article Q135785
  3938.  
  3939. Submitted by V.Ramachandran.
  3940.  
  3941. ----------------------------------------------------------------------
  3942.  
  3943. WDJ SDK Annotation #180
  3944. TYPE:       Win32
  3945. TOPIC:      DRAWITEMSTRUCT
  3946. KEYWORD:    DRAWITEMSTRUCT AND "See also"
  3947.  
  3948. Listviews always set the itemAction member to
  3949. ODA_DRAWENTIRE.  You need to check the itemState member to
  3950. check if the focus or selection needs to be updated. 
  3951.  
  3952. Reference: MSDN KB Article Q131788
  3953.  
  3954. Submitted by V.Ramachandran.
  3955.  
  3956. ----------------------------------------------------------------------
  3957.  
  3958. WDJ MFC Annotation #181
  3959. TYPE:       MFC 4.2
  3960. TOPIC:      CInternetSession::ServiceTypeFromHandle
  3961. KEYWORD:    CInternetSession::ServiceTypeFromHandle
  3962.  
  3963. The on-line help states
  3964. CInternetSession::ServiceTypeFromHandle() returns the type
  3965. of service given the internet handle.  Although this
  3966. function is declared in afxinet.h, it is not defined
  3967. anywhere.  Using this function will cause your program to
  3968. fail at link time. 
  3969.  
  3970. Submitted by Mario Contestabile.
  3971.  
  3972. ----------------------------------------------------------------------
  3973.  
  3974. WDJ MFC Annotation #182
  3975. TYPE:       MFC 4.2
  3976. TOPIC:      CHttpFile::QueryInfo
  3977. KEYWORD:    CHttpFile::QueryInfo
  3978.  
  3979. The documentation for CHttpFile::QueryInfo() erroneously states some of
  3980. the possible values for lpdwIndex and dwIndex: 
  3981.  
  3982.  HTTP_QUERY_LANGUAGE is actually HTTP_QUERY_CONTENT_LANGUAGE
  3983.  HTTP_QUERY_ALLOWED_METHODS is actually HTTP_QUERY_ALLOW
  3984.  HTTP_QUERY_PUBLIC_METHODS is actually HTTP_QUERY_PUBLIC
  3985.  
  3986. (All #defines in wininet.h)
  3987.  
  3988. Submitted by Mario Contestabile.
  3989.  
  3990. ----------------------------------------------------------------------
  3991.  
  3992. WDJ MFC Annotation #183
  3993. TYPE:       MFC 4.x
  3994. TOPIC:      COleDateTime::GetYear
  3995. KEYWORD:    COleDateTime::GetYear
  3996.  
  3997. If the status of this COleDateTime object is not valid, the
  3998. return value is AFX_OLE_DATETIME_ERROR and not
  3999. AFX_DATETIME_ERROR as documented. This affects the following
  4000. member functions: GetYear(), GetMonth(), GetDay(), GetHour(),
  4001. GetMinute(), GetSecond(), GetDayOfWeek(), and GetDayOfYear().
  4002.  
  4003.  
  4004. Submitted by Mario Contestabile.
  4005.  
  4006.  
  4007. ----------------------------------------------------------------------
  4008.  
  4009.  
  4010. WDJ SDK Annotation #184
  4011. TYPE:       Win32
  4012. TOPIC:      ScrollWindowEx
  4013. KEYWORD:    ScrollWindowEx AND "See also"
  4014.  
  4015. If the prcClip parameter is NULL, no clipping is performed on the
  4016. scroll rectangle.
  4017.  
  4018. Submitted by V. Ramachandran.
  4019.  
  4020. ----------------------------------------------------------------------
  4021.  
  4022. WDJ SDK Annotation #185
  4023. TYPE:       Win32
  4024. TOPIC:      WM_CONTEXTMENU
  4025. KEYWORD:    WM_CONTEXTMENU AND "See also"
  4026.  
  4027. If the user uses the keyboard shortcut (Shift-F10 or the special 
  4028. key on a Microsoft keyboard) to activate the context menu, the 
  4029. xPos and yPos parameters are -1, -1.
  4030.  
  4031. Submitted by Katy Mulvey.
  4032.  
  4033. ----------------------------------------------------------------------
  4034.  
  4035. WDJ SDK Annotation #186
  4036. TYPE:       Win32
  4037. TOPIC:      GetLastError
  4038. KEYWORD:    GetLastError AND "return values" AND parameters NOT S_OK
  4039.  
  4040. The Win32 Programmer's Reference documentation for
  4041. GetLastError()  incorrectly states that a listing of the
  4042. error codes is found in  WINNT.H. It is actually found in
  4043. the file WINERROR.H 
  4044.  
  4045. Note: This error has been corrected in the Jan 97 MSDN.
  4046.  
  4047. Submitted by Katy Mulvey.
  4048.  
  4049. ----------------------------------------------------------------------
  4050.  
  4051. WDJ SDK Annotation #187
  4052. TYPE:       Win32
  4053. TOPIC:      CreateWindowEx
  4054. KEYWORD:    CreateWindowEx AND "See also"
  4055.  
  4056. The documentation does not mention that you can call GetLastError
  4057. to get extended error information if the function fails.
  4058.  
  4059. Submitted by V. Ramachandran.
  4060.  
  4061. ----------------------------------------------------------------------
  4062.  
  4063. WDJ SDK Annotation #188
  4064. TYPE:       Win32
  4065. TOPIC:      WM_SYSCOMMAND
  4066. KEYWORD:    WM_SYSCOMMAND AND "See also"
  4067.  
  4068. If the wParam is SC_KEYMENU, the lParam contains the
  4069. character code of the key used in combination with the Alt
  4070. key to display the popup menu. For example, pressing Alt+F
  4071. to display the File popup will cause a WM_SYSCOMMAND with
  4072. wParam equal to SC_KEYMENU and lParam equal to 'f'.
  4073.  
  4074. Reference: MSDN Article ID Q92527.
  4075.  
  4076. Submitted by V. Ramachandran.
  4077.  
  4078. ----------------------------------------------------------------------
  4079.  
  4080. WDJ SDK Annotation #189
  4081. TYPE:       Win32
  4082. TOPIC:      CreateWindow
  4083. KEYWORD:    CreateWindow AND "See also"
  4084.  
  4085. For creating static controls with the SS_ICON style, you
  4086. need to specify the icon name in the lpWindowName parameter.
  4087. However, if you have an icon resource identified with a
  4088. numeric id (instead of a string), you need to specify #xxx
  4089. (where xxx is the numeric identifier for the ICON resource)
  4090. in the lpWindowName  parameter. You should not use the
  4091. MAKEINTRESOURCE macro.
  4092.  
  4093. Submitted by V. Ramachandran.
  4094.  
  4095. ----------------------------------------------------------------------
  4096.  
  4097. WDJ SDK Annotation #189
  4098. TYPE:       Win32
  4099. TOPIC:      CreateWindowEx
  4100. KEYWORD:    CreateWindowEx AND "See also"
  4101.  
  4102. For creating static controls with the SS_ICON style, you
  4103. need to specify the icon name in the lpWindowName parameter.
  4104. However, if you have an icon resource identified with a
  4105. numeric id (instead of a string), you need to specify #xxx
  4106. (where xxx is the numeric identifier for the ICON resource)
  4107. in the lpWindowName  parameter. You should not use the
  4108. MAKEINTRESOURCE macro.
  4109.  
  4110. Submitted by V. Ramachandran.
  4111.  
  4112. ----------------------------------------------------------------------
  4113.  
  4114. WDJ SDK Annotation #190
  4115. TYPE:       Win32
  4116. TOPIC:      WM_GETTEXT
  4117. KEYWORD:    WM_GETTEXT AND "See also"
  4118.  
  4119. In Win32, you cannot send the WM_SETTEXT to a static control
  4120. with the SS_ICON style to set the icon. Therefore, you
  4121. should not use the WM_GETTEXT message to retrieve the icon
  4122. handle of static controls with the SS_ICON style. Use the
  4123. STM_SETICON and STM_GETICON messages instead.
  4124.  
  4125. Submitted by V. Ramachandran.
  4126.  
  4127. ----------------------------------------------------------------------
  4128.  
  4129. WDJ SDK Annotation #191
  4130. TYPE:       Win32
  4131. TOPIC:      RegisterHotKey
  4132. KEYWORD:    RegisterHotKey AND "See also"
  4133.  
  4134. If you want to disable task switching under Win32, you can
  4135. do so by registering hot keys for Ctrl+Esc and Alt+Tab.
  4136.  
  4137. Reference: MSDN Article ID Q125614
  4138. Submitted by V. Ramachandran.
  4139.  
  4140. ----------------------------------------------------------------------
  4141.  
  4142. WDJ SDK Annotation #192
  4143. TYPE:       Win32
  4144. TOPIC:      CreateFile
  4145. KEYWORD:    CreateFile AND "See also"
  4146.  
  4147. Under Windows NT, when CreateFile is used with  the
  4148. dwCreationDistribution parameter equal to CREATE_ALWAYS, 
  4149. the call fails if the file exists and is hidden.
  4150. GetLastError() returns ERROR_ACCESS_DENIED. However, the
  4151. call succeeds under Windows 95 creating a new  file that is
  4152. not hidden.
  4153.  
  4154. Submitted by Abdul Nizar.
  4155.  
  4156. ----------------------------------------------------------------------
  4157.  
  4158. WDJ MFC Annotation #192
  4159. TYPE:       MFC 4.x
  4160. TOPIC:      CFile::Open
  4161. KEYWORD:    CFile::Open
  4162.  
  4163. Under Windows NT, if the nOpenFlags parameter is ORed with 
  4164. CFile::modeCreate and not ORed with CFile::modeNoTruncate, 
  4165. CFile::Open fails if the file exists and is hidden. However,
  4166. the call succeeds under Windows 95 creating a new file that
  4167. is  not hidden.
  4168.  
  4169. Submitted by Abdul Nizar.
  4170.  
  4171.  
  4172. ----------------------------------------------------------------------
  4173.  
  4174. WDJ MFC Annotation #193
  4175. TYPE:       MFC
  4176. TOPIC:      CListCtrl::SetColumnWidth
  4177. KEYWORD:    CListCtrl::SetColumnWidth
  4178.  
  4179. The cx parameter is the new width of the column in listview
  4180. coordinates, or one of the following
  4181.  
  4182.    LVSCW_AUTOSIZE             Automatically sizes the column.
  4183.    LVSCW_AUTOSIZE_USEHEADER   Automatically sizes the column to 
  4184.                               fit the header text
  4185.  
  4186. Submitted by Ramon de Klein. 
  4187.  
  4188. ----------------------------------------------------------------------
  4189.  
  4190.